Skip to content

Commit 930f124

Browse files
committed
Type Checker
1 parent 2c8b58b commit 930f124

File tree

11 files changed

+110
-16
lines changed

11 files changed

+110
-16
lines changed

YukimiScript.CodeGen.Lua/Lua.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ let generateLua (Intermediate scenes) : string =
4444
| Symbol "nil" -> "nil"
4545
| Symbol x -> "api." + x
4646
| Integer x -> string x
47-
| Number x -> string x
47+
| Real x -> string x
4848
| String x -> "\"" + Constants.string2literal x + "\"")
4949

5050
if not <| List.isEmpty args then

YukimiScript.Parser.Test/TestConstants.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ let testNumbers () =
3131

3232
for _ in 0 .. 16 do
3333
let i = float (rnd.Next()) + rnd.NextDouble()
34-
testConstant (string i) <| Number i
34+
testConstant (string i) <| Real i
3535
let j = -(float (rnd.Next()) + rnd.NextDouble())
36-
testConstant (string j) <| Number j
36+
testConstant (string j) <| Real j
3737

38-
testConstant "- 176.00" <| Number -176.0
38+
testConstant "- 176.00" <| Real -176.0
3939

4040

4141
[<Test>]

YukimiScript.Parser.Test/TestStatments.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ let testCommandCall () =
1616
Integer -256 ]
1717
NamedArgs =
1818
[ "effect", Symbol "a"
19-
"camera", Number -2.0 ] }
19+
"camera", Real -2.0 ] }

YukimiScript.Parser/Constants.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ let private numberParser, integerParser =
3333
do! literal "."
3434
let! b = unsignedIntegerString
3535

36-
return Number <| float (sign + a + "." + b)
36+
return Real <| float (sign + a + "." + b)
3737
}
3838
|> name "number"
3939

YukimiScript.Parser/Dom.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ module Dom =
166166
(fun (sceneDef, block, debugInfo) ->
167167
Macro.expandBlock macros block
168168
|> Result.map (fun x -> sceneDef, x, debugInfo))
169-
|> ParserMonad.switchResultList
169+
|> ParserMonad.sequenceRL
170170
|> Result.map (fun scenes -> { x with Scenes = scenes })
171171

172172

@@ -225,9 +225,9 @@ module Dom =
225225

226226
let linkToExternCommands (sceneDef, block, debugInfo) =
227227
List.map linkSingleCommand block
228-
|> ParserMonad.switchResultList
228+
|> ParserMonad.sequenceRL
229229
|> Result.map (fun block -> sceneDef, (block: Block), debugInfo)
230230

231231
List.map linkToExternCommands x.Scenes
232-
|> ParserMonad.switchResultList
232+
|> ParserMonad.sequenceRL
233233
|> Result.map (fun scenes -> { x with Scenes = scenes })

YukimiScript.Parser/Elements.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
type Constant =
55
| String of string
6-
| Number of float
6+
| Real of float
77
| Integer of int32
88
| Symbol of string
99

YukimiScript.Parser/Macro.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ let matchArguments debugInfo (x: Parameter list) (c: CommandCall) : Result<(stri
9292
|> Result.bind
9393
(fun () ->
9494
List.map (fun x -> matchArg x.Parameter) x
95-
|> switchResultList)
95+
|> sequenceRL)
9696

9797

9898
let private matchMacro debug x macro =
@@ -140,19 +140,19 @@ let rec private expandSingleOperation macros operation : Result<Block, exn> =
140140
| x -> x
141141
>> expandSingleOperation macros
142142
)
143-
|> switchResultList
143+
|> sequenceRL
144144
|> Result.map List.concat
145145
| x -> Ok [ x ]
146146

147147

148148
let expandBlock macros (block: Block) =
149149
List.map (expandSingleOperation macros) block
150-
|> switchResultList
150+
|> sequenceRL
151151
|> Result.map List.concat
152152

153153

154154
let expandSystemMacros (block: Block) =
155-
let systemMacros = [ "__diagram_link_to" ]
155+
let systemMacros = [ "__diagram_link_to"; "__type" ]
156156

157157
block
158158
|> List.map

YukimiScript.Parser/Parser.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ let parseLines (line: string []) : Result<Parsed list, (int * exn) list> =
5656
| _ -> None)
5757

5858
if List.isEmpty errors then
59-
match switchResultList parsed with
59+
match sequenceRL parsed with
6060
| Ok x -> Ok x
6161
| _ -> failwith "Internal Error"
6262
else

YukimiScript.Parser/ParserMonad.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let tryWith (f: exn -> Parser<'a>) (a: Parser<'a>) : Parser<'a> =
3939
let explicit (a: Parser<'a>) : Parser<'a> = mapError raise a
4040

4141

42-
let switchResultList (x: Result<'a, 'b> list) : Result<'a list, 'b> =
42+
let sequenceRL (x: Result<'a, 'b> list) : Result<'a list, 'b> =
4343
(x, Ok [])
4444
||> List.foldBack
4545
(fun x state ->

YukimiScript.Parser/TypeChecker.fs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
module YukimiScript.Parser.TypeChecker
2+
3+
open YukimiScript.Parser.Elements
4+
5+
6+
type SimpleType =
7+
| Int'
8+
| Real'
9+
| String'
10+
| Symbol'
11+
12+
13+
type ParameterType = ParameterType of name: string * Set<SimpleType>
14+
15+
16+
module Types =
17+
let any = ParameterType ("any", set [ Int'; Real'; String'; Symbol' ])
18+
let int = ParameterType ("int", set [ Int' ])
19+
let number = ParameterType ("number", set [ Int'; Real' ])
20+
let real = ParameterType ("real", set [ Real' ])
21+
let symbol = ParameterType ("symbol", set [ Symbol' ])
22+
let void' = ParameterType ("void", set [])
23+
let all = [ any; int; number; real; symbol; void' ]
24+
25+
26+
let sumParameterType (ParameterType (n1, s1)) (ParameterType (n2, s2)) =
27+
ParameterType (n1 + " | " + n2, Set.union s1 s2)
28+
29+
30+
let checkType =
31+
function
32+
| String _ -> String'
33+
| Integer _ -> Int'
34+
| Real _ -> Real'
35+
| Symbol _ -> Symbol'
36+
37+
38+
exception TypeCheckFailedException of DebugInformation * int * ParameterType * SimpleType
39+
40+
41+
let matchType d i (ParameterType (t, types)) (argType: SimpleType) : Result<unit, exn> =
42+
if Set.contains argType types
43+
then Ok ()
44+
else Error <| TypeCheckFailedException (d, i, (ParameterType (t, types)), argType)
45+
46+
47+
let matchCallTypes d (pars: ParameterType list) (argType: SimpleType list) =
48+
List.zip pars argType |> List.mapi (fun i (a, b) -> matchType d i a b)
49+
|> ParserMonad.sequenceRL |> Result.map ignore
50+
51+
52+
let matchCall d (pars: ParameterType list) (argType: Constant list) =
53+
argType |> List.map checkType |> matchCallTypes d pars
54+
55+
56+
exception IsNotAType of string
57+
58+
59+
let parametersTypeFromBlock (par: Parameter list) (b: Block) =
60+
let typeMacroParams =
61+
[ { Parameter = "param"; Default = None }
62+
{ Parameter = "type"; Default = None } ]
63+
64+
List.choose (function
65+
| CommandCall c, d when c.Callee = "__type" -> Some (c, d)
66+
| _ -> None) b
67+
|> List.map (fun (c, d) -> Macro.matchArguments d typeMacroParams c)
68+
|> ParserMonad.sequenceRL
69+
|> Result.bind (fun x ->
70+
let paramTypePairs =
71+
List.map (readOnlyDict >> fun x ->
72+
match x["param"], x["type"] with
73+
| Symbol par, Symbol t -> par, t
74+
| _ -> failwith "parametersTypeFromBlock: failed!") x
75+
76+
par
77+
|> List.map (fun { Parameter = name; Default = _ } ->
78+
paramTypePairs
79+
|> List.filter (fst >> (=) name)
80+
|> List.map snd
81+
|> function
82+
| [] -> Ok Types.any
83+
| types ->
84+
types
85+
|> List.map (fun typeName ->
86+
Types.all
87+
|> List.tryFind (fun (ParameterType (n, _)) -> n = typeName)
88+
|> function
89+
| Some x -> Ok x
90+
| None -> Error <| IsNotAType typeName)
91+
|> ParserMonad.sequenceRL
92+
|> Result.map (List.reduce sumParameterType))
93+
|> ParserMonad.sequenceRL)

0 commit comments

Comments
 (0)