@@ -91,59 +91,20 @@ function parsebody(body::Expr)
91
91
# :([f1 => ((X,Y), (Int,Int)),
92
92
# f2 => ((Y,), (X,)) ] )
93
93
# :(Bool[X==Y])
94
+ isassoc (ex:: Expr ) = ex. head== :(= ) # associated types
95
+ isconstraints (ex:: Expr ) = ex. head== :macrocall # constraints
96
+
94
97
outfns = Expr (:dict )
95
98
constr = :(Bool[])
96
99
assoc = quote end
97
100
for ln in Lines (body)
98
- if ln . head == :macrocall # constraints
101
+ if isconstraints (ln)
99
102
parseconstraints! (constr, ln)
100
- elseif ln . head == :( = ) # associated types
103
+ elseif isassoc (ln)
101
104
push! (assoc. args, ln)
102
- else
103
- argtype = :()
104
- rettype = :()
105
-
106
- if ln. head== :tuple
107
- # several ret-types:
108
- # f1(X,Y) -> x,y
109
- append! (rettype. args, ln. args[2 : end ])
110
- ln = ln. args[1 ]
111
- end
112
-
113
- if ln. head== :(-> )
114
- # f1(X,Y) -> x
115
- fn = ln. args[1 ]. args[1 ]
116
- append! (argtype. args, ln. args[1 ]. args[2 : end ])
117
- tmp = rettype
118
- rettype = :()
119
- push! (rettype. args, ln. args[2 ]. args[2 ])
120
- append! (rettype. args, tmp. args)
121
- elseif ln. head== :call
122
- # f1(X,Y) or X + Y -> Z
123
- if isa (ln. args[end ], Expr) && ln. args[end ]. head== :(-> ) # X + Y -> Z
124
- fn = ln. args[1 ]
125
- append! (argtype. args, ln. args[2 : end - 1 ])
126
- if isa (ln. args[end ]. args[1 ], Expr)
127
- append! (argtype. args, ln. args[end ]. args[1 ]. args)
128
- else
129
- push! (argtype. args, ln. args[end ]. args[1 ])
130
- end
131
- tmp = rettype
132
- rettype = :()
133
- push! (rettype. args, ln. args[end ]. args[2 ]. args[2 ])
134
- append! (rettype. args, tmp. args)
135
- else # f1(X,Y)
136
- fn = ln. args[1 ]
137
- append! (argtype. args, ln. args[2 : end ])
138
- rettype = :((Any... ))
139
- end
140
- else
141
- throw (TraitException (
142
- " Something went wrong parsing the trait definition body with line:\n $ln " ))
143
- end
144
- push! (outfns. args, :($ fn => ($ argtype, $ rettype)))
105
+ else # the rest of the body are function signatures
106
+ parsefnstypes! (outfns, ln)
145
107
end
146
-
147
108
end
148
109
# store associated types:
149
110
tmp = :(TypeVar[])
@@ -170,6 +131,71 @@ function parseconstraints!(constr, block)
170
131
end
171
132
end
172
133
134
+ function parsefnstypes! (outfns, ln)
135
+ function parsefn (def)
136
+ # Parse to get function signature.
137
+ # parses f(X,Y), f{X <:T}(X,Y) and X+Y
138
+ if isa (def. args[1 ], Symbol)
139
+ fn = def. args[1 ]
140
+ elseif def. args[1 ]. head== :curly
141
+ fn = def. args[1 ]. args[1 ]
142
+ # todo
143
+ else
144
+ throw (TraitException (
145
+ " Something went wrong parsing the trait definition body with line:\n $ln " ))
146
+ end
147
+ argtype = :()
148
+ append! (argtype. args, def. args[2 : end ])
149
+ return fn, argtype # typvars
150
+ end
151
+ function parseret! (rettype, ln)
152
+ # parse to get return types
153
+ while ln. head!= :block
154
+ ln = ln. args[end ]
155
+ end
156
+ tmp = rettype. args
157
+ rettype. args = Any[]
158
+ push! (rettype. args, ln. args[end ])
159
+ append! (rettype. args, tmp)
160
+ end
161
+
162
+
163
+ rettype = :()
164
+ if ln. head== :tuple
165
+ # several ret-types:
166
+ # f1(X,Y) -> X,Y
167
+ append! (rettype. args, ln. args[2 : end ])
168
+ ln = ln. args[1 ]
169
+ end
170
+
171
+ if ln. head== :(-> ) # f1(X,Y) -> x
172
+ parseret! (rettype, ln)
173
+ fn, argtype = parsefn (ln. args[1 ])
174
+ elseif ln. head== :call # either f1(X,Y) or X + Y -> Z
175
+ if isa (ln. args[end ], Expr) && ln. args[end ]. head== :(-> ) # X + Y -> Z
176
+ def = Expr (:call )
177
+ append! (def. args, ln. args[1 : end - 1 ])
178
+ if length (ln. args)== 2
179
+ append! (def. args, ln. args[end ]. args[1 ]. args)
180
+ else
181
+ push! (def. args, ln. args[end ]. args[1 ])
182
+ end
183
+ parseret! (rettype, ln)
184
+ else # f1(X,Y)
185
+ def = ln
186
+ rettype = :((Any... ))
187
+ end
188
+ fn, argtype = parsefn (def)
189
+ else
190
+ throw (TraitException (
191
+ " Something went wrong parsing the trait definition body with line:\n $ln " ))
192
+ end
193
+ # replace types with constraints by TypeVars
194
+ # ...
195
+
196
+ push! (outfns. args, :($ fn => ($ argtype, $ rettype)))
197
+ end
198
+
173
199
# 3) piece it together
174
200
# ##
175
201
0 commit comments