| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 | open EvalValueopen Typeclass plugin =	object (self)		(**			Prints greeting to stdout.			Takes no arguments, returns Void.		*)		method hello () : value =			print_endline "Hello from plugin";			(*				Plugin architecture requires to return something even for methods typed Void on Haxe side.				Return `null`			*)			vnull		(**			Takes `haxe.macro.Position` and returns a string of that position in the same format used for			compiler errors		*)		method stringify_position (pos:value) : value =			let pos = EvalDecode.decode_pos pos in			let str = Lexer.get_error_pos (Printf.sprintf "%s:%d:") pos in			EvalEncode.encode_string str		(**			Change all static methods named "test" to throw "Hello from plugin".			This is an example how to modify typed syntax tree.		*)		method hijack_static_test () : value =			let compiler = (EvalContext.get_ctx()).curapi in			(**				Add a callback like `haxe.macro.Context.onAfterTyping`			*)			compiler.after_typing (fun haxe_types ->				List.iter					(fun hx_type ->						match hx_type with							| TClassDecl cls ->								List.iter									(fun field ->										match field.cf_name, field.cf_expr with											| "test", Some e ->												let hello = {													eexpr = TConst (TString "Hello from plugin");													etype = (compiler.get_com()).basic.tstring;													epos = Globals.null_pos;												} in												field.cf_expr <- Some { e with eexpr = TThrow hello }											| _ -> ()									)									cls.cl_ordered_statics							| _ -> ()					)					haxe_types			);			vnull	end;;let api = new plugin in(**	Register our plugin API.	This code is executed upon `eval.vm.Context.loadPlugin` call.*)EvalStdLib.StdContext.register [	("hello", EvalEncode.vfun0 api#hello);	("stringifyPosition", EvalEncode.vfun1 api#stringify_position);	("hijackStaticTest", EvalEncode.vfun0 api#hijack_static_test);]
 |