Class: Heist::Runtime

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/heist/runtime/runtime.rb,
lib/heist/runtime/frame.rb,
lib/heist/runtime/scope.rb,
lib/heist/runtime/stack.rb,
lib/heist/runtime/binding.rb,
lib/heist/runtime/data/cons.rb,
lib/heist/runtime/stackless.rb,
lib/heist/runtime/data/value.rb,
lib/heist/runtime/data/vector.rb,
lib/heist/runtime/callable/macro.rb,
lib/heist/runtime/data/character.rb,
lib/heist/runtime/callable/syntax.rb,
lib/heist/runtime/data/expression.rb,
lib/heist/runtime/data/identifier.rb,
lib/heist/runtime/callable/function.rb,
lib/heist/runtime/callable/macro/tree.rb,
lib/heist/runtime/callable/continuation.rb,
lib/heist/runtime/callable/macro/matches.rb,
lib/heist/runtime/callable/macro/expansion.rb

Overview

Runtime objects represent instances of the Heist runtime environment. Each Runtime defines a top-level Scope, into which are injected the standard set of primitive functions and special forms as defined in lib/builtin.

User code runs in another scope descended from the top-level. This is done so that user-level redefinitions of built-in functions do not break other built-in functions that refer to the redefined names; lexical scoping ensures that built-in functions can only refer to other bindings in the top-level scope so user-level bindings do not affect the built-in library functions.

Runtime exposes several methods from the user-level Scope object, allowing runtime objects to be used as interfaces for defining functions, eval’ing code and running source files.

Defined Under Namespace

Modules: Expression Classes: Binding, Body, Character, Cons, Continuation, FileScope, Frame, Function, Identifier, Macro, Scope, Stack, Stackless, Syntax, Value, Vector

Constant Summary collapse

BUILTIN_LIBRARIES =
%w[primitives syntax compiled_library]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Runtime

A Runtime is initialized using a set of options. The available options include the following, all of which are false unless you override them yourself:

  • :continuations: set to true to enable call/cc

  • :lazy: set to true to enable lazy evaluation

  • :unhygienic: set to true to disable macro hygiene



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/heist/runtime/runtime.rb', line 46

def initialize(options = {})
  @lazy          = !!options[:lazy]
  @continuations = !!options[:continuations]
  @hygienic      = !options[:unhygienic]
  
  @top_level  = Scope.new(self)
  @user_scope = Scope.new(@top_level)
  @stack      = stackless? ? Stackless.new : Stack.new
  
  load_builtins(options)
  @start_time = Time.now.to_f
end

Instance Attribute Details

#stackObject

Returns the value of attribute stack.



34
35
36
# File 'lib/heist/runtime/runtime.rb', line 34

def stack
  @stack
end

#top_levelObject

Returns the value of attribute top_level.



34
35
36
# File 'lib/heist/runtime/runtime.rb', line 34

def top_level
  @top_level
end

#user_scopeObject

Returns the value of attribute user_scope.



34
35
36
# File 'lib/heist/runtime/runtime.rb', line 34

def user_scope
  @user_scope
end

Instance Method Details

#elapsed_timeObject

Returns the length of time the Runtime has been alive for, as a number in microseconds.



74
75
76
# File 'lib/heist/runtime/runtime.rb', line 74

def elapsed_time
  (Time.now.to_f - @start_time) * 1000000
end

#hygienic?Boolean

Returns true iff the Runtime is using hygienic macros.

Returns:

  • (Boolean)


82
# File 'lib/heist/runtime/runtime.rb', line 82

def hygienic?; @hygienic; end

#infoObject



97
98
99
100
101
102
103
# File 'lib/heist/runtime/runtime.rb', line 97

def info
  [ "Heist Scheme interpreter v. #{ VERSION }",
    "Evaluation mode: #{ lazy? ? 'LAZY' : 'EAGER' }",
    "Continuations enabled? #{ stackless? ? 'NO' : 'YES' }",
    "Macros: #{ hygienic? ? 'HYGIENIC' : 'UNHYGIENIC' }\n\n"
  ] * "\n"
end

#lazy?Boolean

Returns true iff the Runtime is using lazy evaluation.

Returns:

  • (Boolean)


79
# File 'lib/heist/runtime/runtime.rb', line 79

def lazy?; @lazy; end

#load_builtins(options = {}) ⇒ Object

To stop user-space redefinitions of built-in functions from breaking the standard library, we define builtins in a privileged scope, one up from the scope that user code runs in. We then bind the names in ‘user space’ to stop (set!) from reaching into our privileged top level.



63
64
65
66
67
68
69
70
# File 'lib/heist/runtime/runtime.rb', line 63

def load_builtins(options = {})
  libraries = (options[:only] || BUILTIN_LIBRARIES) - (options[:except] || [])
  
  libraries.each do |library|
    @top_level.run(@top_level.expand_path(library))
  end
  @user_scope.each_var(&@user_scope.method(:[]=))
end

#stackless?Boolean

Returns true iff the Runtime is using the faster Stackless evaluator, which does not support (call/cc).

Returns:

  • (Boolean)


86
87
88
# File 'lib/heist/runtime/runtime.rb', line 86

def stackless?
  lazy? or not @continuations
end

#to_sObject Also known as: inspect



90
91
92
93
94
# File 'lib/heist/runtime/runtime.rb', line 90

def to_s
  "#<runtime: #{ stackless? ? 'call/cc disabled' : 'call/cc enabled'
           }, #{ hygienic? ? 'hygienic' : 'unhygienic'
           }, #{ lazy? ? 'lazy' : 'eager' }>"
end