Skip to content

Commit b9bde9f

Browse files
committed
Merge branch 'ty-serialization'
2 parents a5caa31 + 3dec5b5 commit b9bde9f

File tree

2 files changed

+300
-0
lines changed

2 files changed

+300
-0
lines changed

src/comp/front/creader.rs

Lines changed: 184 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,187 @@ 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) -> u8 {
39+
if (st.pos < st.len) {ret st.rep.(st.pos) as u8;}
40+
else {ret ' ' as u8;}
41+
}
42+
impure fn next(@pstate st) -> u8 { // ?? 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 u8;
47+
}
48+
49+
impure 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_mt(@pstate st, str_def sd) -> ty.mt {
63+
auto mut;
64+
alt (peek(st) as char) {
65+
case ('m') {next(st); mut = ast.mut;}
66+
case ('?') {next(st); mut = ast.maybe_mut;}
67+
case (_) {mut=ast.imm;}
68+
}
69+
ret rec(ty=parse_ty(st, sd), mut=mut);
70+
}
71+
72+
impure fn parse_sty(@pstate st, str_def sd) -> ty.sty {
73+
alt (next(st) as char) {
74+
case ('n') {ret ty.ty_nil;}
75+
case ('b') {ret ty.ty_bool;}
76+
case ('i') {ret ty.ty_int;}
77+
case ('u') {ret ty.ty_uint;}
78+
case ('M') {
79+
alt (next(st) as char) {
80+
case ('b') {ret ty.ty_machine(common.ty_u8);}
81+
case ('w') {ret ty.ty_machine(common.ty_u16);}
82+
case ('l') {ret ty.ty_machine(common.ty_u32);}
83+
case ('d') {ret ty.ty_machine(common.ty_u64);}
84+
case ('B') {ret ty.ty_machine(common.ty_i8);}
85+
case ('W') {ret ty.ty_machine(common.ty_i16);}
86+
case ('L') {ret ty.ty_machine(common.ty_i32);}
87+
case ('D') {ret ty.ty_machine(common.ty_i64);}
88+
case ('f') {ret ty.ty_machine(common.ty_f32);}
89+
case ('F') {ret ty.ty_machine(common.ty_f64);}
90+
}
91+
}
92+
case ('c') {ret ty.ty_char;}
93+
case ('s') {ret ty.ty_str;}
94+
case ('t') {
95+
check(next(st) as char == '[');
96+
auto def = "";
97+
while (peek(st) as char != '|') {
98+
def += _str.unsafe_from_byte(next(st));
99+
}
100+
st.pos = st.pos + 1u;
101+
let vec[@ty.t] params = vec();
102+
while (peek(st) as char != ']') {
103+
params += vec(parse_ty(st, sd));
104+
}
105+
st.pos = st.pos + 1u;
106+
ret ty.ty_tag(sd(def), params);
107+
}
108+
case ('@') {ret ty.ty_box(parse_mt(st, sd));}
109+
case ('V') {ret ty.ty_vec(parse_mt(st, sd));}
110+
case ('P') {ret ty.ty_port(parse_ty(st, sd));}
111+
case ('C') {ret ty.ty_chan(parse_ty(st, sd));}
112+
case ('T') {
113+
check(next(st) as char == '[');
114+
let vec[ty.mt] params = vec();
115+
while (peek(st) as char != ']') {
116+
params += vec(parse_mt(st, sd));
117+
}
118+
st.pos = st.pos + 1u;
119+
ret ty.ty_tup(params);
120+
}
121+
case ('R') {
122+
check(next(st) as char == '[');
123+
let vec[ty.field] fields = vec();
124+
while (peek(st) as char != ']') {
125+
auto name = "";
126+
while (peek(st) as char != '=') {
127+
name += _str.unsafe_from_byte(next(st));
128+
}
129+
st.pos = st.pos + 1u;
130+
fields += vec(rec(ident=name, mt=parse_mt(st, sd)));
131+
}
132+
st.pos = st.pos + 1u;
133+
ret ty.ty_rec(fields);
134+
}
135+
case ('F') {
136+
auto func = parse_ty_fn(st, sd);
137+
ret ty.ty_fn(ast.proto_fn, func._0, func._1);
138+
}
139+
case ('W') {
140+
auto func = parse_ty_fn(st, sd);
141+
ret ty.ty_fn(ast.proto_iter, func._0, func._1);
142+
}
143+
case ('N') {
144+
auto abi;
145+
alt (next(st) as char) {
146+
case ('r') {abi = ast.native_abi_rust;}
147+
case ('c') {abi = ast.native_abi_cdecl;}
148+
}
149+
auto func = parse_ty_fn(st, sd);
150+
ret ty.ty_native_fn(abi,func._0,func._1);
151+
}
152+
case ('O') {
153+
check(next(st) as char == '[');
154+
let vec[ty.method] methods = vec();
155+
while (peek(st) as char != ']') {
156+
auto proto;
157+
alt (next(st) as char) {
158+
case ('W') {proto = ast.proto_iter;}
159+
case ('F') {proto = ast.proto_fn;}
160+
}
161+
auto name = "";
162+
while (peek(st) as char != '[') {
163+
name += _str.unsafe_from_byte(next(st));
164+
}
165+
auto func = parse_ty_fn(st, sd);
166+
methods += vec(rec(proto=proto,
167+
ident=name,
168+
inputs=func._0,
169+
output=func._1));
170+
}
171+
ret ty.ty_obj(methods);
172+
}
173+
case ('X') {ret ty.ty_var(parse_int(st));}
174+
case ('E') {ret ty.ty_native;}
175+
}
176+
}
177+
178+
impure fn parse_int(@pstate st) -> int {
179+
auto n = 0;
180+
while (true) {
181+
auto cur = peek(st) as char;
182+
if (cur < '0' || cur > '9') {break;}
183+
st.pos = st.pos + 1u;
184+
n *= 10;
185+
n += (cur as int) - ('0' as int);
186+
}
187+
ret n;
188+
}
189+
190+
impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) {
191+
check(next(st) as char == '[');
192+
let vec[ty.arg] inputs = vec();
193+
while (peek(st) as char != ']') {
194+
auto mode = ast.val;
195+
if (peek(st) as char == '&') {
196+
mode = ast.alias;
197+
st.pos = st.pos + 1u;
198+
}
199+
inputs += vec(rec(mode=mode, ty=parse_ty(st, sd)));
200+
}
201+
st.pos = st.pos + 1u;
202+
ret tup(inputs, parse_ty(st, sd));
203+
}
204+
205+
206+
23207
// TODO: return something
24208
fn load_crate(ast.ident ident, vec[str] library_search_paths) -> @() {
25209
for (str library_search_path in library_search_paths) {

src/comp/middle/metadata.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,128 @@
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 mt_str(&ty.mt mt, def_str ds) -> str {
30+
auto mut_str;
31+
alt (mt.mut) {
32+
case (ast.imm) { mut_str = ""; }
33+
case (ast.mut) { mut_str = "m"; }
34+
case (ast.maybe_mut) { mut_str = "?"; }
35+
}
36+
ret mut_str + ty_str(mt.ty, ds);
37+
}
38+
39+
fn sty_str(ty.sty st, def_str ds) -> str {
40+
alt (st) {
41+
case (ty.ty_nil) {ret "n";}
42+
case (ty.ty_bool) {ret "b";}
43+
case (ty.ty_int) {ret "i";}
44+
case (ty.ty_uint) {ret "u";}
45+
case (ty.ty_machine(?mach)) {
46+
alt (mach) {
47+
case (common.ty_u8) {ret "Mb";}
48+
case (common.ty_u16) {ret "Mw";}
49+
case (common.ty_u32) {ret "Ml";}
50+
case (common.ty_u64) {ret "Md";}
51+
case (common.ty_i8) {ret "MB";}
52+
case (common.ty_i16) {ret "MW";}
53+
case (common.ty_i32) {ret "ML";}
54+
case (common.ty_i64) {ret "MD";}
55+
case (common.ty_f32) {ret "Mf";}
56+
case (common.ty_f64) {ret "MF";}
57+
}
58+
}
59+
case (ty.ty_char) {ret "c";}
60+
case (ty.ty_str) {ret "s";}
61+
case (ty.ty_tag(?def,?tys)) { // TODO restore def_id
62+
auto acc = "t[" + ds(def) + "|";
63+
for (@ty.t t in tys) {acc += ty_str(t, ds);}
64+
ret acc + "]";
65+
}
66+
case (ty.ty_box(?mt)) {ret "@" + mt_str(mt, ds);}
67+
case (ty.ty_vec(?mt)) {ret "V" + mt_str(mt, ds);}
68+
case (ty.ty_port(?t)) {ret "P" + ty_str(t, ds);}
69+
case (ty.ty_chan(?t)) {ret "C" + ty_str(t, ds);}
70+
case (ty.ty_tup(?mts)) {
71+
auto acc = "T[";
72+
for (ty.mt mt in mts) {acc += mt_str(mt, ds);}
73+
ret acc + "]";
74+
}
75+
case (ty.ty_rec(?fields)) {
76+
auto acc = "R[";
77+
for (ty.field field in fields) {
78+
acc += field.ident + "=";
79+
acc += mt_str(field.mt, ds);
80+
}
81+
ret acc + "]";
82+
}
83+
case (ty.ty_fn(?proto,?args,?out)) {
84+
ret proto_str(proto) + ty_fn_str(args, out, ds);
85+
}
86+
case (ty.ty_native_fn(?abi,?args,?out)) {
87+
auto abistr;
88+
alt (abi) {
89+
case (ast.native_abi_rust) {abistr = "r";}
90+
case (ast.native_abi_cdecl) {abistr = "c";}
91+
}
92+
ret "N" + abistr + ty_fn_str(args, out, ds);
93+
}
94+
case (ty.ty_obj(?methods)) {
95+
auto acc = "O[";
96+
for (ty.method m in methods) {
97+
acc += proto_str(m.proto);
98+
acc += m.ident;
99+
acc += ty_fn_str(m.inputs, m.output, ds);
100+
}
101+
ret acc + "]";
102+
}
103+
case (ty.ty_var(?id)) {ret "X" + common.istr(id);}
104+
case (ty.ty_native) {ret "E";}
105+
// TODO (maybe?) ty_param(ast.def_id), ty_type;
106+
}
107+
}
108+
109+
fn proto_str(ast.proto proto) -> str {
110+
alt (proto) {
111+
case (ast.proto_iter) {ret "W";}
112+
case (ast.proto_fn) {ret "F";}
113+
}
114+
}
115+
116+
fn ty_fn_str(vec[ty.arg] args, @ty.t out, def_str ds) -> str {
117+
auto acc = "[";
118+
for (ty.arg arg in args) {
119+
if (arg.mode == ast.alias) {acc += "&";}
120+
acc += ty_str(arg.ty, ds);
121+
}
122+
ret acc + "]" + ty_str(out, ds);
123+
}
124+
125+
10126
// Returns a Plain Old LLVM String.
11127
fn C_postr(str s) -> ValueRef {
12128
ret llvm.LLVMConstString(_str.buf(s), _str.byte_len(s), False);

0 commit comments

Comments
 (0)