@@ -6,11 +6,14 @@ import lib.llvm.llvmext;
6
6
import lib. llvm . mk_object_file ;
7
7
import lib. llvm . mk_section_iter ;
8
8
import middle. fold ;
9
+ import middle. ty ;
9
10
import util. common ;
10
11
import util. common . span ;
11
12
12
13
import std. _str ;
14
+ import std. _vec ;
13
15
import std. fs ;
16
+ import std. option ;
14
17
import std. os ;
15
18
import std. map . hashmap ;
16
19
@@ -20,6 +23,174 @@ type env = @rec(
20
23
vec[ str] library_search_paths
21
24
) ;
22
25
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 + 1 u;
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=0 u, 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 + 1 u;
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 + 1 u;
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 + 1 u;
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 + 1 u;
116
+ fields = _vec. push [ ty. field ]
117
+ ( fields, rec ( ident=name, ty=parse_ty ( st, sd) ) ) ;
118
+ }
119
+ st. pos = st. pos + 1 u;
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 + 1 u;
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 + 1 u;
184
+ }
185
+ inputs = _vec. push [ ty. arg ]
186
+ ( inputs, rec ( mode=mode, ty=parse_ty ( st, sd) ) ) ;
187
+ }
188
+ st. pos = st. pos + 1 u;
189
+ ret tup( inputs, parse_ty ( st, sd) ) ;
190
+ }
191
+
192
+
193
+
23
194
// TODO: return something
24
195
fn load_crate ( ast . ident ident, vec[ str] library_search_paths ) -> @( ) {
25
196
for ( str library_search_path in library_search_paths) {
0 commit comments