11module internal YukimiScript.Parser.Macro
22
33open YukimiScript.Parser .Elements
4+ open TypeChecker
45open ParserMonad
56open Basics
67open Constants
@@ -96,16 +97,18 @@ let matchArguments debugInfo (x: Parameter list) (c: CommandCall) : Result<(stri
9697
9798
9899let private matchMacro debug x macro =
99- let pred ( macro : MacroDefination , _ ) = macro.Name = x.Callee
100+ let pred ( macro : MacroDefination , _ , _ ) = macro.Name = x.Callee
100101
101102 match List.tryFind pred macro with
102103 | None -> Error NoMacroMatchedException
103- | Some ( macro, _) when macro.Param.Length < x.UnnamedArgs.Length ->
104+ | Some ( macro, _, _ ) when macro.Param.Length < x.UnnamedArgs.Length ->
104105 Error
105106 <| ArgumentsTooMuchException( debug, macro, x)
106- | Some ( macro, other) ->
107+ | Some ( macro, t , other) ->
107108 matchArguments debug macro.Param x
109+ |> Result.bind ( checkApplyTypeCorrect debug t)
108110 |> Result.map ( fun args -> macro, other, args)
111+
109112
110113
111114let private replaceParamToArgs args macroBody =
@@ -131,7 +134,7 @@ let rec private expandSingleOperation macros operation : Result<Block, exn> =
131134 | Ok ( macro, macroBody: Block, args) ->
132135 let macros =
133136 macros
134- |> List.filter ( fun ( x , _ ) -> x.Name <> macro.Name)
137+ |> List.filter ( fun ( x , _ , _ ) -> x.Name <> macro.Name)
135138
136139 macroBody
137140 |> List.map (
@@ -159,3 +162,60 @@ let expandSystemMacros (block: Block) =
159162 ( function
160163 | CommandCall cmdCall, dbg when List.exists ((=) cmdCall.Callee) systemMacros -> EmptyLine, dbg
161164 | x -> x)
165+
166+
167+ let parametersTypeFromBlock ( par : Parameter list ) ( b : Block ) : Result < BlockParamTypes , exn > =
168+ let typeMacroParams =
169+ [ { Parameter = " param" ; Default = None }
170+ { Parameter = " type" ; Default = None } ]
171+
172+ let typeMacroParamsTypes =
173+ [ " param" , Types.symbol
174+ " type" , Types.symbol ]
175+
176+ List.choose ( function
177+ | CommandCall c, d when c.Callee = " __type" -> Some ( c, d)
178+ | _ -> None) b
179+ |> List.map ( fun ( c , d ) ->
180+ matchArguments d typeMacroParams c
181+ |> Result.bind ( checkApplyTypeCorrect d typeMacroParamsTypes)
182+ |> Result.map ( fun x -> x, d))
183+ |> sequenceRL
184+ |> Result.bind ( fun x ->
185+ let paramTypePairs =
186+ List.map ( fun ( x , d ) ->
187+ x
188+ |> readOnlyDict
189+ |> fun x ->
190+ match x.[ " param" ], x.[ " type" ] with
191+ | Symbol par, Symbol t -> par, t, d
192+ | _ -> failwith " parametersTypeFromBlock: failed!" ) x
193+
194+ let dummy =
195+ paramTypePairs
196+ |> List.filter ( not << fun ( n , _ , d ) ->
197+ List.exists ( fun p -> p.Parameter = n) par)
198+ |> List.map ( fun ( n , _ , d ) -> n, d)
199+
200+ if List.length dummy = 0
201+ then
202+ par
203+ |> List.map ( fun { Parameter = name ; Default = _ } ->
204+ paramTypePairs
205+ |> List.filter ((=) name << fun ( n , _ , _ ) -> n)
206+ |> List.map ( fun ( _ , t , d ) -> t, d)
207+ |> function
208+ | [] -> Ok ( name, Types.any)
209+ | types ->
210+ types
211+ |> List.map ( fun ( typeName , d ) ->
212+ Types.all
213+ |> List.tryFind ( fun ( ParameterType ( n , _ )) -> n = typeName)
214+ |> function
215+ | Some x -> Ok x
216+ | None -> Error <| IsNotAType typeName)
217+ |> sequenceRL
218+ |> Result.map ( fun t ->
219+ name, List.reduce sumParameterType t))
220+ |> sequenceRL
221+ else Error <| CannotGetParameterException dummy)
0 commit comments