From e1e736840ed8c925e2ff442861963250a72d4385 Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Tue, 24 Oct 2017 13:08:15 +0200 Subject: Update sheet traversal --- sheet.ml | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'sheet.ml') diff --git a/sheet.ml b/sheet.ml index 256a5a1..a31c9ef 100755 --- a/sheet.ml +++ b/sheet.ml @@ -10,8 +10,6 @@ type search = [ module Raw = struct - exception Cycle - module Map = Map.Make(struct type t = cell let compare (x1, y1) (x2, y2) = Pervasives.compare (y1, x1) (y2, x2) @@ -30,7 +28,7 @@ module Raw = struct (** An empty cell which does contains nothing *) let empty_cell = { - expr = Expression.load @@ UTF8.empty; + expr = Expression.Undefined; value = None; sink = Cell.Set.empty; } @@ -73,7 +71,7 @@ module Raw = struct (* If the previous value wasn't defined, update the map *) Some (Map.add cell { content with value = Some new_val } t) | Some old_value -> - (* If the previous value was defined, update only if both differs *) + (* If the previous value was defined, update only if result differs *) if not (ScTypes.Result.(=) new_val old_value) then Some (Map.add cell { content with value = Some new_val } t) else @@ -89,19 +87,25 @@ module Raw = struct let rec successors element (parents, succ, t) = begin let content = Map.find element t in + if Cell.Set.mem element parents then ( (* if the cell has already been visited, mark it in error, and all the descendant *) - let cycle_error = Some (ScTypes.Error Cycle) in - let t = Map.add element { content with value = cycle_error} t - and set_error cell content t = - if content.value = cycle_error then - None - else - Some (Map.add cell { content with value = cycle_error} t) in - let succ = Cell.Set.add element succ in - let succ, t = traverse set_error content (succ, t) in - (Cell.Set.empty, succ, t) + let cycle_error = Some (ScTypes.Error Errors.Cycle) in + + if content.value = cycle_error then + (* The content has already been update, do not process it again *) + (Cell.Set.empty, succ, t) + else + let t = Map.add element { content with value = cycle_error} t + and set_error cell content t = + if content.value = cycle_error then + None + else + Some (Map.add cell { content with value = cycle_error} t) + and succ = Cell.Set.add element succ in + let succ, t = traverse set_error content (succ, t) in + (Cell.Set.empty, succ, t) ) else ( begin match f element content t with | None -> @@ -117,7 +121,7 @@ module Raw = struct end ) end in - let _, succ, t = Cell.Set.fold successors source.sink (Cell.Set.empty, init, t) in + let _, succ, t = Cell.Set.fold successors source.sink (init, init, t) in succ, t end -- cgit v1.2.3