Class: Fusion::Interpreter::Thunk

Inherits:
Object
  • Object
show all
Defined in:
lib/fusion/interpreter/thunk.rb

Defined Under Namespace

Classes: ReadFailure

Instance Method Summary collapse

Constructor Details

#initialize(&compute) ⇒ Thunk

Returns a new instance of Thunk.



16
17
18
19
20
# File 'lib/fusion/interpreter/thunk.rb', line 16

def initialize(&compute)
  @compute = compute
  @state = :unforced # :unforced | :forcing | :done
  @value = nil # memoized result: runtime value/error | ReadFailure
end

Instance Method Details

#force(operation: "loading code", input: NULL, site: { origin: "code", file: nil }) ⇒ Object

operation/input/site describe the @-reference forcing this thunk. They are NOT passed to @compute, because they differ when evaluating the same Thunk for different @-references. They MUST NOT become part or the memoized value.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/fusion/interpreter/thunk.rb', line 25

def force(operation: "loading code", input: NULL, site: { origin: "code", file: nil })
  result = case @state
  when :done
    @value
  when :forcing
    # Re-entering while still computing results in a non-productive data cycle. Not memoized.
    ErrorVal.from_runtime(kind: "reference_error", **site, operation: operation, input: input, message: "non-productive data cycle")
  when :unforced
    @state = :forcing
    begin
      @value = @compute.call
    rescue ReadFailure => failure
      # Memoize the Ruby error itself. Turn it into a Fusion runtime error below.
      @value = failure
    end
    @state = :done
    @value
  end

  case result
  when ReadFailure
    ErrorVal.from_runtime(kind: "reference_error", **site, operation: operation, input: input, message: result.message)
  else
    result
  end
end