Scope.fs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. module Qsp.Parser.Scope
  2. open FsharpMyExtension
  3. type VarId = int
  4. type 'VarName Scopes when 'VarName : comparison = Map<'VarName, VarId> list
  5. type ScopeSystem<'VarName, 'Value> when 'VarName : comparison =
  6. {
  7. Scopes: 'VarName Scopes
  8. NewVarId: VarId
  9. Result : Map<VarId, 'VarName * 'Value list>
  10. }
  11. let scopeSystemEmpty =
  12. {
  13. Scopes = [Map.empty]
  14. NewVarId = 0
  15. Result = Map.empty
  16. }
  17. let addAsRead (varName:'VarName, getValue) (scopeSystem: ScopeSystem<_,_>) =
  18. let result = scopeSystem.Result
  19. let rec f acc (scopes:_ Scopes) =
  20. match scopes with
  21. | [m] ->
  22. match Map.tryFind varName m with
  23. | Some varId ->
  24. let result =
  25. let x = mapSnd getValue result.[varId]
  26. Map.add varId x result
  27. let scopes =
  28. List.fold (fun xs x -> x::xs) scopes acc
  29. let x =
  30. {
  31. Scopes = scopes
  32. NewVarId = scopeSystem.NewVarId
  33. Result = result
  34. }
  35. varId, x
  36. | None ->
  37. let m = Map.add varName scopeSystem.NewVarId m
  38. let result =
  39. Map.add scopeSystem.NewVarId (varName, getValue []) result
  40. let scopes =
  41. List.fold (fun xs x -> x::xs) [m] acc
  42. let x =
  43. {
  44. Scopes = scopes
  45. NewVarId = scopeSystem.NewVarId + 1
  46. Result = result
  47. }
  48. scopeSystem.NewVarId, x
  49. | m::ms ->
  50. match Map.tryFind varName m with
  51. | Some varId ->
  52. let result =
  53. let x = mapSnd getValue result.[varId]
  54. Map.add varId x result
  55. let scopes =
  56. List.fold (fun xs x -> x::xs) scopes acc
  57. let x =
  58. {
  59. Scopes = scopes
  60. NewVarId = scopeSystem.NewVarId
  61. Result = result
  62. }
  63. varId, x
  64. | None ->
  65. f (m::acc) ms
  66. | [] -> failwith "the scope cannot be empty"
  67. f [] scopeSystem.Scopes
  68. let addAsWrite (varName:'VarName, getValue) (scopeSystem: ScopeSystem<_,_>) =
  69. match scopeSystem.Scopes with
  70. | m::ms ->
  71. match Map.tryFind varName m with
  72. | None ->
  73. let newVarId = scopeSystem.NewVarId
  74. let m = Map.add varName newVarId m
  75. let result =
  76. Map.add newVarId (varName, getValue []) scopeSystem.Result
  77. let scopes = m::ms
  78. let x =
  79. {
  80. NewVarId = newVarId + 1
  81. Scopes = scopes
  82. Result = result
  83. }
  84. newVarId, x
  85. | Some varId ->
  86. let m = Map.add varName varId m
  87. let result = scopeSystem.Result
  88. let result =
  89. let x = mapSnd getValue result.[varId]
  90. Map.add varId x result
  91. let scopes = m::ms
  92. let x =
  93. {
  94. NewVarId = scopeSystem.NewVarId
  95. Scopes = scopes
  96. Result = result
  97. }
  98. varId, x
  99. | [] -> failwith "the scope cannot be empty"
  100. let appendScope (scopes:_ Scopes) = Map.empty::scopes
  101. let removeScope (scopes:_ Scopes) =
  102. match scopes with
  103. | x::xs -> xs
  104. | [] -> failwith "scopes is empty"
  105. let test () =
  106. let init =
  107. {
  108. Scopes = [Map.empty]
  109. NewVarId = 0
  110. Result = Map.empty
  111. }
  112. let (_, x) = addAsRead ("x", (fun xs -> (0, 0)::xs)) init
  113. addAsRead ("x", (fun xs -> (0, 0)::xs)) x