Class: Loxxy::BackEnd::LoxFunction

Inherits:
Object
  • Object
show all
Defined in:
lib/loxxy/back_end/lox_function.rb

Overview

rubocop: disable Style/AccessorGrouping Representation of a Lox function.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(aName, parameterList, aBody, anEngine) ⇒ LoxFunction

Create a function with given name

Parameters:

  • aName (String)

    The name of the function



22
23
24
25
26
27
28
29
30
# File 'lib/loxxy/back_end/lox_function.rb', line 22

def initialize(aName, parameterList, aBody, anEngine)
  @name = aName.dup
  @parameters = parameterList
  @body = aBody.kind_of?(Ast::LoxNoopExpr) ? aBody : aBody.subnodes[0]
  @engine = anEngine
  @closure = anEngine.symbol_table.current_env
  @is_initializer = false
  anEngine.symbol_table.current_env.embedding = true
end

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



15
16
17
# File 'lib/loxxy/back_end/lox_function.rb', line 15

def body
  @body
end

#closureObject (readonly)

Returns the value of attribute closure.



17
18
19
# File 'lib/loxxy/back_end/lox_function.rb', line 17

def closure
  @closure
end

#engineObject (readonly)

Returns the value of attribute engine.



16
17
18
# File 'lib/loxxy/back_end/lox_function.rb', line 16

def engine
  @engine
end

#is_initializerObject

Returns the value of attribute is_initializer.



18
19
20
# File 'lib/loxxy/back_end/lox_function.rb', line 18

def is_initializer
  @is_initializer
end

#nameString (readonly)

Returns The name of the function (if any).

Returns:

  • (String)

    The name of the function (if any)



11
12
13
# File 'lib/loxxy/back_end/lox_function.rb', line 11

def name
  @name
end

#parametersArray<> (readonly)

Returns the parameters.

Returns:

  • (Array<>)

    the parameters



14
15
16
# File 'lib/loxxy/back_end/lox_function.rb', line 14

def parameters
  @parameters
end

Instance Method Details

#!Datatype::False

Logical negation. As a function is a truthy thing, its negation is thus false.

Returns:



80
81
82
# File 'lib/loxxy/back_end/lox_function.rb', line 80

def !
  Datatype::False.instance
end

#accept(_visitor) ⇒ Object



36
37
38
# File 'lib/loxxy/back_end/lox_function.rb', line 36

def accept(_visitor)
  engine.expr_stack.push self
end

#arityObject



32
33
34
# File 'lib/loxxy/back_end/lox_function.rb', line 32

def arity
  parameters ? parameters.size : 0
end

#bind(anInstance) ⇒ Object



67
68
69
70
71
72
73
74
75
# File 'lib/loxxy/back_end/lox_function.rb', line 67

def bind(anInstance)
  new_env = Environment.new(closure)
  this = Variable.new('this', anInstance)
  new_env.insert(this)
  bound_method = dup
  bound_method.instance_variable_set(:@closure, new_env)

  bound_method
end

#call(_engine, aVisitor) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/loxxy/back_end/lox_function.rb', line 40

def call(_engine, aVisitor)
  new_env = Environment.new(closure)
  engine.symbol_table.enter_environment(new_env)

  parameters&.each do |param_name|
    local = Variable.new(param_name, engine.stack.pop)
    engine.symbol_table.insert(local)
  end

  catch(:return) do
    body.accept(aVisitor) unless body.nil? || body.kind_of?(Ast::LoxNoopExpr)
    # implicit return at end of function...
    engine.stack.push(Datatype::Nil.instance) unless is_initializer
  end
  # Compensate for deeply nested return
  engine.symbol_table.leave_environment while engine.current_env != new_env

  if is_initializer
    enclosing_env = engine.symbol_table.current_env.enclosing
    engine.stack.push(enclosing_env.defns['this'].value)
  end

  engine.symbol_table.leave_environment
  # engine.expr_stack.clear
  engine.expr_stack.push(engine.stack.pop) unless engine.stack.empty?
end

#to_strObject

Text representation of a Lox function



85
86
87
# File 'lib/loxxy/back_end/lox_function.rb', line 85

def to_str
  "<fn #{name}>"
end