1. kevinclancy
  2. love studio

Commits

kevinclancy  committed 0afc9e7

now handling nested deductions properly

  • Participants
  • Parent commits 0981c3f
  • Branches default

Comments (0)

Files changed (2)

File LoveStudio/LuaAnalyzer/Type.fs

View file
  • Ignore whitespace
     /// Generate a deduced Type for when an field of type original 
     /// has been determined to have type deduced.
     static member MakeDeducedTy (original : Type) (deduced : Type) =
-        match original with
-        | DeducedTy(permOriginal,_) ->
-            DeducedTy(permOriginal,deduced)
-        | _ ->
-            DeducedTy(original,deduced)
+        
+        let perm =
+            match original with
+            | DeducedTy(permOriginal,_) ->
+                permOriginal
+            | _ ->
+                original
+
+        let temp =
+            match deduced with
+            | DeducedTy(_,deducedOriginal) ->
+                deducedOriginal
+            | _ ->
+                deduced
     
+        DeducedTy(perm,temp)
+
     static member Flatten (ty : Type) =
         match ty with
         | TupleTy(lst) ->
         | x ->
             [x]
 
-    static member ApplyDeduction (baseField : Field) (fields : List<string>) (targetField : Field) (isNewField : bool) =
+    member this.StripNillable() =
+        match this with
+        | NillableTy(ty) ->
+            ty.StripNillable()
+        | _ ->
+            this
+
+    static member ApplyDeduction (tenv : TypeEnvironment) (baseField : Field) (fields : List<string>) (targetField : Field) (isNewField : bool) =
         let rec applyAt (accField : Field) (fields : List<string>) (targetField : Field) =
             match fields with
             | [last] ->
                 let lastField = 
-                    match accField.ty with
+                    let ty = Type.Coerce tenv accField.ty
+                    match ty with
                     | RecordTy(_,_,_,_,fields,_,_) 
                     | OpenRecordTy(_,_,_,_,fields,_,_) when fields.ContainsKey last ->
-                        accField.ty.[last]
+                        ty.[last]
                     | OpenRecordTy(_,_,_,_,_,_,_) ->
                         targetField
                     | _ ->
                     RecordTy(a,b,c,d,fields.Add(last,newLast),e,f)
                 | OpenRecordTy(a,b,c,d,fields,e,f) ->
                     OpenRecordTy(a,b,c,d,fields.Add(last,newLast),e,f)   
+                | DeducedTy(a,RecordTy(b,c,d,e,fields,f,g)) ->
+                    DeducedTy(a,RecordTy(b,c,d,e,fields.Add(last,newLast),f,g))
+                | DeducedTy(a,OpenRecordTy(b,c,d,e,fields,f,g)) ->
+                    DeducedTy(a,OpenRecordTy(b,c,d,e,fields.Add(last,newLast),f,g))
                 | _ ->
                     UnknownTy
             
             | head :: rest ->
-                match accField.ty with 
+                match Type.Coerce tenv accField.ty with 
                 | RecordTy(a,b,c,d,fields,e,f) ->
                     let headField = 
                         if fields.ContainsKey head then
                             Field.OfType(UnknownTy)
                     let deduced = { headField with ty = applyAt headField rest targetField }
                     OpenRecordTy(a,b,c,d,fields.Add(head,deduced),e,f)
+                | DeducedTy(a, RecordTy(b,c,d,e,fields,f,g)) ->
+                    let headField = 
+                        if fields.ContainsKey head then
+                            fields.[head]
+                        else
+                            Field.OfType(UnknownTy)
+                    let deduced = { headField with ty = applyAt headField rest targetField }
+                    DeducedTy(a,RecordTy(b,c,d,e,fields.Add(head,deduced),f,g))
+                | DeducedTy(a, OpenRecordTy(b,c,d,e,fields,f,g)) ->
+                    let headField = 
+                        if fields.ContainsKey head then
+                            fields.[head]
+                        else
+                            Field.OfType(UnknownTy)
+                    let deduced = { headField with ty = applyAt headField rest targetField }
+                    DeducedTy(a,OpenRecordTy(b,c,d,e,fields.Add(head,deduced),f,g))                    
                 | _ ->
                     UnknownTy
               
                     RecordTy(a,b,c,d,fields.Add(last,undoneLast),e,f)
                 | OpenRecordTy(a,b,c,d,fields,e,f) ->
                     OpenRecordTy(a,b,c,d,fields.Add(last,undoneLast),e,f)   
+                | DeducedTy(a,RecordTy(b,c,d,e,fields,f,g)) ->
+                    DeducedTy(a,RecordTy(b,c,d,e,fields.Add(last,undoneLast),f,g))
+                | DeducedTy(a,OpenRecordTy(b,c,d,e,fields,f,g)) ->
+                    DeducedTy(a,OpenRecordTy(b,c,d,e,fields,f,g))
                 | _ ->
                     UnknownTy           
                 
                     let headField = fields.[head]
                     let undone = { headField with ty = undoAt rest headField }
                     OpenRecordTy(a,b,c,d,fields.Add(head,undone),e,f)
+                | DeducedTy(a,RecordTy(b,c,d,e,fields,f,g)) ->
+                    let headField = fields.[head]
+                    let undone = { headField with ty = undoAt rest headField }
+                    DeducedTy(a,RecordTy(b,c,d,e,fields.Add(head,undone),f,g))                    
+                | DeducedTy(a,OpenRecordTy(b,c,d,e,fields,f,g)) ->
+                    let headField = fields.[head]
+                    let undone = { headField with ty = undoAt rest headField }
+                    DeducedTy(a,OpenRecordTy(b,c,d,e,fields.Add(head,undone),f,g))
                 | _ ->
                     UnknownTy
             | _ ->
             Type.Coerce env ty
         | DeducedTy(_,temp) ->
             Type.Coerce env temp
+        | UserDefinedTy(_) ->
+            Type.Coerce env (Type.Unfold env ty)
         | _ ->
-            Type.Unfold env ty
+            ty
 
 /// (description, rhsType, retTy) for binary operator
 and BinOpTy = string*Type*Type

File LoveStudio/LuaAnalyzer/Typechecker.fs

View file
  • Ignore whitespace
     if ctxt.venv.ContainsKey path.Head then
         let value = ctxt.venv.[path.Head]
         let isNewField = not (ctxt.HasValPath path) 
-        ctxt.AddValue(path.Head, { value with ty = Type.ApplyDeduction value path.Tail target isNewField }) 
+        ctxt.AddValue(path.Head, { value with ty = Type.ApplyDeduction ctxt.tenv value path.Tail target isNewField }) 
     else
         ctxt