@@ -12,8 +12,6 @@ open Hh_prelude
12
12
module Value = struct
13
13
type t =
14
14
| Str of string (* * String values *)
15
- | ClassPtr of Nast .class_ (* * References to class definitions *)
16
- | MethodPtr of Nast .method_ (* * References to method definitions *)
17
15
| Error (* * Represents evaluation errors *)
18
16
19
17
(* Helper functions to safely extract values from the Value.t type.
@@ -25,19 +23,6 @@ module Value = struct
25
23
let str = function
26
24
| Str s -> Some s
27
25
| _ -> None
28
-
29
- let str_ish = function
30
- | Str s -> Some s
31
- | ClassPtr c -> Some (Utils. strip_ns @@ snd c.Aast. c_name)
32
- | _ -> None
33
-
34
- let class_ptr = function
35
- | ClassPtr c -> Some c
36
- | _ -> None
37
-
38
- let method_ptr = function
39
- | MethodPtr m -> Some m
40
- | _ -> None
41
26
end
42
27
43
28
(* Context module maintains the interpreter's state during evaluation *)
@@ -123,6 +108,24 @@ module Context = struct
123
108
let find_method ~ctx :_ class_ name =
124
109
List. find class_.Aast. c_methods ~f: (fun meth ->
125
110
String. equal (snd meth.Aast. m_name) name)
111
+
112
+ (* * [find_function ~ctx name] looks up a function definition by name using the context's provider
113
+ Returns [None] if the function is not found
114
+
115
+ Example:
116
+ {[
117
+ match Context.find_function ~ctx "myFunction" with
118
+ | Some func_def -> (* Use function definition *)
119
+ | None -> (* Handle missing function *)
120
+ ]}
121
+ *)
122
+ let find_function ~ctx name =
123
+ let open Option.Let_syntax in
124
+ let * path = Naming_provider. get_fun_path ctx.provider name in
125
+ let * fun_def =
126
+ Ast_provider. find_fun_in_file ~full: true ctx.provider path name
127
+ in
128
+ return @@ Naming. fun_def ctx.provider fun_def
126
129
end
127
130
128
131
(* ControlFlow module represents the possible outcomes of statement evaluation *)
@@ -157,28 +160,18 @@ end = struct
157
160
~init: (Some " " )
158
161
~f: (fun acc e ->
159
162
let * lhs = acc in
160
- let * rhs = Value. str_ish @@ expr ctx e in
163
+ let * rhs = Value. str @@ expr ctx e in
161
164
return @@ lhs ^ rhs)
162
165
exprs
163
166
in
164
167
return @@ Value. Str value
168
+ | Aast. Nameof (_ , _ , Aast. CI (_ , name )) -> return @@ Value. Str name
165
169
| Aast. Lvar (_ , name ) ->
166
170
(* Looks up value of a local variable *)
167
171
Context. load ~ctx name
168
- | Aast. Class_const (cid, (_, id))
169
- when String. equal id Naming_special_names.Members. mClass ->
170
- (* Handles class constant access for getting class pointer *)
171
- let * class_ = ClassId. eval ctx cid in
172
- return @@ Value. ClassPtr class_
173
- | Aast. Class_const (cid , (_ , id )) ->
174
- (* Handles method reference through class constant access *)
175
- let * class_ = ClassId. eval ctx cid in
176
- let * meth = Context. find_method ~ctx class_ id in
177
- return @@ Value. MethodPtr meth
178
172
| Aast. (Call { func; targs = _ ; args; unpacked_arg = None } ) ->
179
173
(* Evaluates a function/method call *)
180
- let * meth = Value. method_ptr @@ expr ctx func in
181
- Call. eval ctx meth args
174
+ Call. eval ctx func args
182
175
| Aast. (Binop { bop; lhs; rhs } ) ->
183
176
(* Handles binary operations *)
184
177
Binop. eval ctx bop lhs rhs
@@ -239,21 +232,20 @@ end = struct
239
232
240
233
let class_id (ctx : Context.t ) (ClassId cid ) =
241
234
match cid with
242
- | Aast. (CIparent | CIself | CIstatic ) ->
235
+ | Aast. (CIparent | CIself | CIstatic | CIexpr _ ) ->
243
236
None (* Special class refs not supported *)
244
237
| Aast. CI (_ , name ) -> Context. find_class ~ctx name (* Named class *)
245
- | Aast. CIexpr e -> Value. class_ptr @@ Expr. eval ctx e (* Class expression *)
246
238
247
239
let eval (ctx : Context.t ) (_ , _ , cid ) = class_id ctx (ClassId cid)
248
240
end
249
241
250
242
(* Call module handles function/method calls *)
251
243
and Call : sig
252
244
val eval :
253
- Context .t -> Nast .method_ -> (_ , _ ) Aast .argument list -> Value .t option
245
+ Context .t -> ( _ , _ ) Aast .expr -> (_ , _ ) Aast .argument list -> Value .t option
254
246
end = struct
255
247
(* Build new context for function call with arguments *)
256
- let build_ctx ~ctx func args =
248
+ let build_ctx ~ctx params args =
257
249
let eval = Expr. eval ctx in
258
250
let rec go args params ctx =
259
251
match (args, params) with
@@ -262,15 +254,33 @@ end = struct
262
254
@@ Context. store ~ctx (Local_id. make_unscoped param_name) (eval arg)
263
255
| _ -> ctx
264
256
in
265
- go args func.Aast. m_params @@ Context. fresh ctx
257
+ go args params @@ Context. fresh ctx
258
+
259
+ let invoke ctx (params , body ) args =
260
+ let ctx = build_ctx ~ctx params args in
261
+ let { Aast. fb_ast } = body in
262
+ Block. eval ctx fb_ast
266
263
267
264
(* Evaluate function call *)
268
265
let eval
269
- (ctx : Context.t ) (func : Nast.method_ ) (args : (_, _) Aast.argument list )
270
- =
271
- let ctx = build_ctx ~ctx func args in
272
- let { Aast. fb_ast } = func.Aast. m_body in
273
- Block. eval ctx fb_ast
266
+ (ctx : Context.t )
267
+ (func : (_, _) Aast.expr )
268
+ (args : (_, _) Aast.argument list ) =
269
+ let open Option.Let_syntax in
270
+ let (_, _, func) = func in
271
+ match func with
272
+ | Aast. Id (_ , name ) ->
273
+ let * Aast. { fd_fun = { f_params = params; f_body = body; _ }; _ } =
274
+ Context. find_function ~ctx name
275
+ in
276
+ invoke ctx (params, body) args
277
+ | Aast. Class_const (cid , (_ , name )) ->
278
+ let * class_ = ClassId. eval ctx cid in
279
+ let * Aast. { m_params = params; m_body = body; _ } =
280
+ Context. find_method ~ctx class_ name
281
+ in
282
+ invoke ctx (params, body) args
283
+ | _ -> None
274
284
end
275
285
276
286
(* Binop module handles binary operations *)
@@ -286,8 +296,8 @@ end = struct
286
296
match bop with
287
297
| Ast_defs. Dot ->
288
298
let open Option.Let_syntax in
289
- let * lhs_str = Value. str_ish @@ Expr. eval ctx lhs_expr in
290
- let * rhs_str = Value. str_ish @@ Expr. eval ctx rhs_expr in
299
+ let * lhs_str = Value. str @@ Expr. eval ctx lhs_expr in
300
+ let * rhs_str = Value. str @@ Expr. eval ctx rhs_expr in
291
301
Some (Value. Str (lhs_str ^ rhs_str))
292
302
| _ -> None
293
303
end
0 commit comments