Class: Campa::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/campa/context.rb

Overview

Represents a storage for all bindings in any Campa execution.

All functions run inside their own context so when they are finished any binding created by it will be gone.

The Repl also uses it’s own Context for execution.

Direct Known Subclasses

Lisp::Core

Instance Method Summary collapse

Constructor Details

#initialize(env = {}) ⇒ Context

Returns a new instance of Context.

Parameters:

  • env (#[], #[]=) (defaults to: {})

    a Hash like or another Campa::Context object to be used as the underlying storage for this Campa::Context.



16
17
18
# File 'lib/campa/context.rb', line 16

def initialize(env = {})
  @env = env
end

Instance Method Details

#[](symbol) ⇒ Object

Returns the value bound to a Symbol

Parameters:

Returns:

  • Object



35
36
37
38
39
# File 'lib/campa/context.rb', line 35

def [](symbol)
  return env[symbol] if env.include?(symbol)

  fallback[symbol] if !fallback.nil?
end

#[]=(symbol, value) ⇒ Object

Creates a new binding between a given Symbol and an Object.

Parameters:

  • symbol (Symbol)

    (actually, nothing guarantees it will be a symbol right now) to be bound to a value in this Campa::Context.

  • value (Object)

    associated to a given Symbol



26
27
28
# File 'lib/campa/context.rb', line 26

def []=(symbol, value)
  env[symbol] = value
end

#bindingsObject

Return the current bindings in an Array.

Examples:

A simple Campa::Context with two bound Symbol

ctx = Context.new(
  Symbol.new("lol") => "what time is it?",
  Symbol.new("bbq") => 420,
)
ctx.bindings #=> [
  [Symbol.new("lol"), "what time is it?"],
  [Symbol.new("bbq"), 420]
]


82
83
84
# File 'lib/campa/context.rb', line 82

def bindings
  @bindings ||= env.is_a?(Context) ? env.bindings : env.to_a
end

#include?(symbol) ⇒ Boolean

Check if there is any binding for a Symbol

Parameters:

  • symbol (Symbol)

    “label” for a (possibly) bound value

Returns:

  • (Boolean)


44
45
46
47
# File 'lib/campa/context.rb', line 44

def include?(symbol)
  env.include?(symbol) ||
    (!fallback.nil? && fallback.include?(symbol))
end

#push(new_env = {}) ⇒ Context

Creates a new Campa::Context assigning self as a #fallback to it.

This means that if a Symbol is not present on the returned Campa::Context, it will be searched on this one. Which allows for building some sort of stack of Campa::Contexts.

WARNING: The name push on this API is very questionable, I would like to change this to a visually more telling API.

Parameters:

  • new_env (#[], #[]=) (defaults to: {})

    a Hash like or a Campa::Context that will serve as a fallback.

Returns:



62
63
64
65
66
67
68
69
# File 'lib/campa/context.rb', line 62

def push(new_env = {})
  # Context is explicit here instead of self.class.new
  # because we can inherit a context
  # like the Lisp::Core does.
  # In this case we want a normal context when pushing to it
  # (and not a Lisp::Core).
  Context.new(new_env).tap { |c| c.fallback = self }
end