Skip to content

Commit 86d0565

Browse files
marijnhpcwalton
authored andcommitted
rustc: Merge in type serialization and deserialization
Signed-off-by: Patrick Walton <[email protected]>
1 parent 0366f5a commit 86d0565

File tree

2 files changed

+277
-0
lines changed

2 files changed

+277
-0
lines changed

src/comp/front/creader.rs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ import lib.llvm.llvmext;
66
import lib.llvm.mk_object_file;
77
import lib.llvm.mk_section_iter;
88
import middle.fold;
9+
import middle.ty;
910
import util.common;
1011
import util.common.span;
1112

1213
import std._str;
14+
import std._vec;
1315
import std.fs;
16+
import std.option;
1417
import std.os;
1518
import std.map.hashmap;
1619

@@ -20,6 +23,174 @@ type env = @rec(
2023
vec[str] library_search_paths
2124
);
2225

26+
// Type decoding
27+
28+
// Compact string representation for ty.t values. API ty_str & parse_from_str.
29+
// (The second has to be authed pure.) Extra parameters are for converting
30+
// to/from def_ids in the string rep. Whatever format you choose should not
31+
// contain pipe characters.
32+
33+
// Callback to translate defs to strs or back.
34+
type str_def = fn(str) -> ast.def_id;
35+
36+
type pstate = rec(str rep, mutable uint pos, uint len);
37+
38+
fn peek(@pstate st) -> char {
39+
if (st.pos < st.len) {ret st.rep.(st.pos) as char;}
40+
else {ret ' ';}
41+
}
42+
impure fn next(@pstate st) -> char { // ?? somehow not recognized as impure
43+
if (st.pos >= st.len) {fail;}
44+
auto ch = st.rep.(st.pos);
45+
st.pos = st.pos + 1u;
46+
ret ch as char;
47+
}
48+
49+
fn parse_ty_str(str rep, str_def sd) -> @ty.t {
50+
auto len = _str.byte_len(rep);
51+
auto st = @rec(rep=rep, mutable pos=0u, len=len);
52+
auto result = parse_ty(st, sd);
53+
check(st.pos == len);
54+
ret result;
55+
}
56+
57+
impure fn parse_ty(@pstate st, str_def sd) -> @ty.t {
58+
ret @rec(struct=parse_sty(st, sd),
59+
cname=option.none[str]);
60+
}
61+
62+
impure fn parse_sty(@pstate st, str_def sd) -> ty.sty {
63+
alt (next(st)) {
64+
case ('n') {ret ty.ty_nil;}
65+
case ('b') {ret ty.ty_bool;}
66+
case ('i') {ret ty.ty_int;}
67+
case ('u') {ret ty.ty_uint;}
68+
case ('M') {
69+
alt (next(st)) {
70+
case ('b') {ret ty.ty_machine(common.ty_u8);}
71+
case ('w') {ret ty.ty_machine(common.ty_u16);}
72+
case ('l') {ret ty.ty_machine(common.ty_u32);}
73+
case ('d') {ret ty.ty_machine(common.ty_u64);}
74+
case ('B') {ret ty.ty_machine(common.ty_i8);}
75+
case ('W') {ret ty.ty_machine(common.ty_i16);}
76+
case ('L') {ret ty.ty_machine(common.ty_i32);}
77+
case ('D') {ret ty.ty_machine(common.ty_i64);}
78+
case ('f') {ret ty.ty_machine(common.ty_f32);}
79+
case ('F') {ret ty.ty_machine(common.ty_f64);}
80+
}
81+
}
82+
case ('c') {ret ty.ty_char;}
83+
case ('s') {ret ty.ty_str;}
84+
case ('t') {
85+
check(next(st) == '[');
86+
auto def = "";
87+
while (peek(st) != '|') {def += _str.from_char(next(st));}
88+
st.pos = st.pos + 1u;
89+
let vec[@ty.t] params = vec();
90+
while (peek(st) != ']') {
91+
params = _vec.push[@ty.t](params, parse_ty(st, sd));
92+
}
93+
st.pos = st.pos + 1u;
94+
ret ty.ty_tag(sd(def), params);
95+
}
96+
case ('@') {ret ty.ty_box(parse_ty(st, sd));}
97+
case ('V') {ret ty.ty_vec(parse_ty(st, sd));}
98+
case ('P') {ret ty.ty_port(parse_ty(st, sd));}
99+
case ('C') {ret ty.ty_chan(parse_ty(st, sd));}
100+
case ('T') {
101+
check(next(st) == '[');
102+
let vec[@ty.t] params = vec();
103+
while (peek(st) != ']') {
104+
params = _vec.push[@ty.t](params, parse_ty(st, sd));
105+
}
106+
st.pos = st.pos + 1u;
107+
ret ty.ty_tup(params);
108+
}
109+
case ('R') {
110+
check(next(st) == '[');
111+
let vec[ty.field] fields = vec();
112+
while (peek(st) != ']') {
113+
auto name = "";
114+
while (peek(st) != '=') {name += _str.from_char(next(st));}
115+
st.pos = st.pos + 1u;
116+
fields = _vec.push[ty.field]
117+
(fields, rec(ident=name, ty=parse_ty(st, sd)));
118+
}
119+
st.pos = st.pos + 1u;
120+
ret ty.ty_rec(fields);
121+
}
122+
case ('F') {
123+
auto func = parse_ty_fn(st, sd);
124+
ret ty.ty_fn(ast.proto_fn, func._0, func._1);
125+
}
126+
case ('W') {
127+
auto func = parse_ty_fn(st, sd);
128+
ret ty.ty_fn(ast.proto_iter, func._0, func._1);
129+
}
130+
case ('N') {
131+
auto abi;
132+
alt (next(st)) {
133+
case ('r') {abi = ast.native_abi_rust;}
134+
case ('c') {abi = ast.native_abi_cdecl;}
135+
}
136+
auto func = parse_ty_fn(st, sd);
137+
ret ty.ty_native_fn(abi,func._0,func._1);
138+
}
139+
case ('O') {
140+
check(next(st) == '[');
141+
let vec[ty.method] methods = vec();
142+
while (peek(st) != ']') {
143+
auto proto;
144+
alt (next(st)) {
145+
case ('W') {proto = ast.proto_iter;}
146+
case ('F') {proto = ast.proto_fn;}
147+
}
148+
auto name = "";
149+
while (peek(st) != '[') {name += _str.from_char(next(st));}
150+
auto func = parse_ty_fn(st, sd);
151+
methods = _vec.push[ty.method]
152+
(methods, rec(proto=proto,
153+
ident=name,
154+
inputs=func._0,
155+
output=func._1));
156+
}
157+
ret ty.ty_obj(methods);
158+
}
159+
case ('X') {ret ty.ty_var(parse_int(st));}
160+
case ('E') {ret ty.ty_native;}
161+
}
162+
}
163+
164+
impure fn parse_int(@pstate st) -> int {
165+
auto n = 0;
166+
while (true) {
167+
auto cur = peek(st);
168+
if (cur < '0' || cur > '9') {break;}
169+
st.pos = st.pos + 1u;
170+
n *= 10;
171+
n += (cur as int) - ('0' as int);
172+
}
173+
ret n;
174+
}
175+
176+
impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) {
177+
check(next(st) == '[');
178+
let vec[ty.arg] inputs = vec();
179+
while (peek(st) != ']') {
180+
auto mode = ast.val;
181+
if (peek(st) == '&') {
182+
mode = ast.alias;
183+
st.pos = st.pos + 1u;
184+
}
185+
inputs = _vec.push[ty.arg]
186+
(inputs, rec(mode=mode, ty=parse_ty(st, sd)));
187+
}
188+
st.pos = st.pos + 1u;
189+
ret tup(inputs, parse_ty(st, sd));
190+
}
191+
192+
193+
23194
// TODO: return something
24195
fn load_crate(ast.ident ident, vec[str] library_search_paths) -> @() {
25196
for (str library_search_path in library_search_paths) {

src/comp/middle/metadata.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,118 @@
11
import std._str;
2+
import std._vec;
3+
import std.option;
4+
25
import front.ast;
36
import middle.trans;
7+
import middle.ty;
48
import back.x86;
9+
import util.common;
510

611
import lib.llvm.llvm;
712
import lib.llvm.llvm.ValueRef;
813
import lib.llvm.False;
914

15+
// Type encoding
16+
17+
// Compact string representation for ty.t values. API ty_str & parse_from_str.
18+
// (The second has to be authed pure.) Extra parameters are for converting
19+
// to/from def_ids in the string rep. Whatever format you choose should not
20+
// contain pipe characters.
21+
22+
// Callback to translate defs to strs or back.
23+
type def_str = fn(ast.def_id) -> str;
24+
25+
fn ty_str(@ty.t t, def_str ds) -> str {
26+
ret sty_str(t.struct, ds);
27+
}
28+
29+
fn sty_str(ty.sty st, def_str ds) -> str {
30+
alt (st) {
31+
case (ty.ty_nil) {ret "n";}
32+
case (ty.ty_bool) {ret "b";}
33+
case (ty.ty_int) {ret "i";}
34+
case (ty.ty_uint) {ret "u";}
35+
case (ty.ty_machine(?mach)) {
36+
alt (mach) {
37+
case (common.ty_u8) {ret "Mb";}
38+
case (common.ty_u16) {ret "Mw";}
39+
case (common.ty_u32) {ret "Ml";}
40+
case (common.ty_u64) {ret "Md";}
41+
case (common.ty_i8) {ret "MB";}
42+
case (common.ty_i16) {ret "MW";}
43+
case (common.ty_i32) {ret "ML";}
44+
case (common.ty_i64) {ret "MD";}
45+
case (common.ty_f32) {ret "Mf";}
46+
case (common.ty_f64) {ret "MF";}
47+
}
48+
}
49+
case (ty.ty_char) {ret "c";}
50+
case (ty.ty_str) {ret "s";}
51+
case (ty.ty_tag(?def,?tys)) { // TODO restore def_id
52+
auto acc = "t[" + ds(def) + "|";
53+
for (@ty.t t in tys) {acc += ty_str(t, ds);}
54+
ret acc + "]";
55+
}
56+
case (ty.ty_box(?t)) {ret "@" + ty_str(t, ds);}
57+
case (ty.ty_vec(?t)) {ret "V" + ty_str(t, ds);}
58+
case (ty.ty_port(?t)) {ret "P" + ty_str(t, ds);}
59+
case (ty.ty_chan(?t)) {ret "C" + ty_str(t, ds);}
60+
case (ty.ty_tup(?tys)) {
61+
auto acc = "T[";
62+
for (@ty.t t in tys) {acc += ty_str(t, ds);}
63+
ret acc + "]";
64+
}
65+
case (ty.ty_rec(?fields)) {
66+
auto acc = "R[";
67+
for (ty.field field in fields) {
68+
acc += field.ident + "=";
69+
acc += ty_str(field.ty, ds);
70+
}
71+
ret acc + "]";
72+
}
73+
case (ty.ty_fn(?proto,?args,?out)) {
74+
ret proto_str(proto) + ty_fn_str(args, out, ds);
75+
}
76+
case (ty.ty_native_fn(?abi,?args,?out)) {
77+
auto abistr;
78+
alt (abi) {
79+
case (ast.native_abi_rust) {abistr = "r";}
80+
case (ast.native_abi_cdecl) {abistr = "c";}
81+
}
82+
ret "N" + abistr + ty_fn_str(args, out, ds);
83+
}
84+
case (ty.ty_obj(?methods)) {
85+
auto acc = "O[";
86+
for (ty.method m in methods) {
87+
acc += proto_str(m.proto);
88+
acc += m.ident;
89+
acc += ty_fn_str(m.inputs, m.output, ds);
90+
}
91+
ret acc + "]";
92+
}
93+
case (ty.ty_var(?id)) {ret "X" + common.istr(id);}
94+
case (ty.ty_native) {ret "E";}
95+
// TODO (maybe?) ty_param(ast.def_id), ty_type;
96+
}
97+
}
98+
99+
fn proto_str(ast.proto proto) -> str {
100+
alt (proto) {
101+
case (ast.proto_iter) {ret "W";}
102+
case (ast.proto_fn) {ret "F";}
103+
}
104+
}
105+
106+
fn ty_fn_str(vec[ty.arg] args, @ty.t out, def_str ds) -> str {
107+
auto acc = "[";
108+
for (ty.arg arg in args) {
109+
if (arg.mode == ast.alias) {acc += "&";}
110+
acc += ty_str(arg.ty, ds);
111+
}
112+
ret acc + "]" + ty_str(out, ds);
113+
}
114+
115+
10116
// Returns a Plain Old LLVM String.
11117
fn C_postr(str s) -> ValueRef {
12118
ret llvm.LLVMConstString(_str.buf(s), _str.byte_len(s), False);

0 commit comments

Comments
 (0)