diff options
| author | Marijn Haverbeke <[email protected]> | 2011-03-21 11:35:04 -0700 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2011-03-21 11:35:04 -0700 |
| commit | 86d05655b48af5aa2bea7c0e191d0cbe22810e29 (patch) | |
| tree | 1ac36ef007cb8fff509f84c1a73f53c069b59f91 /src/comp/front/creader.rs | |
| parent | Add some C99 and C++ compatibility headers for MSVC (diff) | |
| download | rust-86d05655b48af5aa2bea7c0e191d0cbe22810e29.tar.xz rust-86d05655b48af5aa2bea7c0e191d0cbe22810e29.zip | |
rustc: Merge in type serialization and deserialization
Signed-off-by: Patrick Walton <[email protected]>
Diffstat (limited to 'src/comp/front/creader.rs')
| -rw-r--r-- | src/comp/front/creader.rs | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs index b922b378..89a19fc2 100644 --- a/src/comp/front/creader.rs +++ b/src/comp/front/creader.rs @@ -6,11 +6,14 @@ import lib.llvm.llvmext; import lib.llvm.mk_object_file; import lib.llvm.mk_section_iter; import middle.fold; +import middle.ty; import util.common; import util.common.span; import std._str; +import std._vec; import std.fs; +import std.option; import std.os; import std.map.hashmap; @@ -20,6 +23,174 @@ type env = @rec( vec[str] library_search_paths ); +// Type decoding + +// Compact string representation for ty.t values. API ty_str & parse_from_str. +// (The second has to be authed pure.) Extra parameters are for converting +// to/from def_ids in the string rep. Whatever format you choose should not +// contain pipe characters. + +// Callback to translate defs to strs or back. +type str_def = fn(str) -> ast.def_id; + +type pstate = rec(str rep, mutable uint pos, uint len); + +fn peek(@pstate st) -> char { + if (st.pos < st.len) {ret st.rep.(st.pos) as char;} + else {ret ' ';} +} +impure fn next(@pstate st) -> char { // ?? somehow not recognized as impure + if (st.pos >= st.len) {fail;} + auto ch = st.rep.(st.pos); + st.pos = st.pos + 1u; + ret ch as char; +} + +fn parse_ty_str(str rep, str_def sd) -> @ty.t { + auto len = _str.byte_len(rep); + auto st = @rec(rep=rep, mutable pos=0u, len=len); + auto result = parse_ty(st, sd); + check(st.pos == len); + ret result; +} + +impure fn parse_ty(@pstate st, str_def sd) -> @ty.t { + ret @rec(struct=parse_sty(st, sd), + cname=option.none[str]); +} + +impure fn parse_sty(@pstate st, str_def sd) -> ty.sty { + alt (next(st)) { + case ('n') {ret ty.ty_nil;} + case ('b') {ret ty.ty_bool;} + case ('i') {ret ty.ty_int;} + case ('u') {ret ty.ty_uint;} + case ('M') { + alt (next(st)) { + case ('b') {ret ty.ty_machine(common.ty_u8);} + case ('w') {ret ty.ty_machine(common.ty_u16);} + case ('l') {ret ty.ty_machine(common.ty_u32);} + case ('d') {ret ty.ty_machine(common.ty_u64);} + case ('B') {ret ty.ty_machine(common.ty_i8);} + case ('W') {ret ty.ty_machine(common.ty_i16);} + case ('L') {ret ty.ty_machine(common.ty_i32);} + case ('D') {ret ty.ty_machine(common.ty_i64);} + case ('f') {ret ty.ty_machine(common.ty_f32);} + case ('F') {ret ty.ty_machine(common.ty_f64);} + } + } + case ('c') {ret ty.ty_char;} + case ('s') {ret ty.ty_str;} + case ('t') { + check(next(st) == '['); + auto def = ""; + while (peek(st) != '|') {def += _str.from_char(next(st));} + st.pos = st.pos + 1u; + let vec[@ty.t] params = vec(); + while (peek(st) != ']') { + params = _vec.push[@ty.t](params, parse_ty(st, sd)); + } + st.pos = st.pos + 1u; + ret ty.ty_tag(sd(def), params); + } + case ('@') {ret ty.ty_box(parse_ty(st, sd));} + case ('V') {ret ty.ty_vec(parse_ty(st, sd));} + case ('P') {ret ty.ty_port(parse_ty(st, sd));} + case ('C') {ret ty.ty_chan(parse_ty(st, sd));} + case ('T') { + check(next(st) == '['); + let vec[@ty.t] params = vec(); + while (peek(st) != ']') { + params = _vec.push[@ty.t](params, parse_ty(st, sd)); + } + st.pos = st.pos + 1u; + ret ty.ty_tup(params); + } + case ('R') { + check(next(st) == '['); + let vec[ty.field] fields = vec(); + while (peek(st) != ']') { + auto name = ""; + while (peek(st) != '=') {name += _str.from_char(next(st));} + st.pos = st.pos + 1u; + fields = _vec.push[ty.field] + (fields, rec(ident=name, ty=parse_ty(st, sd))); + } + st.pos = st.pos + 1u; + ret ty.ty_rec(fields); + } + case ('F') { + auto func = parse_ty_fn(st, sd); + ret ty.ty_fn(ast.proto_fn, func._0, func._1); + } + case ('W') { + auto func = parse_ty_fn(st, sd); + ret ty.ty_fn(ast.proto_iter, func._0, func._1); + } + case ('N') { + auto abi; + alt (next(st)) { + case ('r') {abi = ast.native_abi_rust;} + case ('c') {abi = ast.native_abi_cdecl;} + } + auto func = parse_ty_fn(st, sd); + ret ty.ty_native_fn(abi,func._0,func._1); + } + case ('O') { + check(next(st) == '['); + let vec[ty.method] methods = vec(); + while (peek(st) != ']') { + auto proto; + alt (next(st)) { + case ('W') {proto = ast.proto_iter;} + case ('F') {proto = ast.proto_fn;} + } + auto name = ""; + while (peek(st) != '[') {name += _str.from_char(next(st));} + auto func = parse_ty_fn(st, sd); + methods = _vec.push[ty.method] + (methods, rec(proto=proto, + ident=name, + inputs=func._0, + output=func._1)); + } + ret ty.ty_obj(methods); + } + case ('X') {ret ty.ty_var(parse_int(st));} + case ('E') {ret ty.ty_native;} + } +} + +impure fn parse_int(@pstate st) -> int { + auto n = 0; + while (true) { + auto cur = peek(st); + if (cur < '0' || cur > '9') {break;} + st.pos = st.pos + 1u; + n *= 10; + n += (cur as int) - ('0' as int); + } + ret n; +} + +impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) { + check(next(st) == '['); + let vec[ty.arg] inputs = vec(); + while (peek(st) != ']') { + auto mode = ast.val; + if (peek(st) == '&') { + mode = ast.alias; + st.pos = st.pos + 1u; + } + inputs = _vec.push[ty.arg] + (inputs, rec(mode=mode, ty=parse_ty(st, sd))); + } + st.pos = st.pos + 1u; + ret tup(inputs, parse_ty(st, sd)); +} + + + // TODO: return something fn load_crate(ast.ident ident, vec[str] library_search_paths) -> @() { for (str library_search_path in library_search_paths) { |