Class: Twostroke::Runtime::Types::Function

Inherits:
Object
  • Object
show all
Defined in:
lib/twostroke/runtime/types/function.rb

Instance Attribute Summary collapse

Attributes inherited from Object

#_class, #accessors, #data, #extensible, #properties

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Object

#can_put, #construct, #constructing?, #default_value, #define_own_property, #delete, #delete!, #each_enumerable_property, #generic_items, #get, #get_own_property, #get_property, #has_accessor, #has_own_property, #has_property, #proto_put, #put, set_global_prototype

Constructor Details

#initialize(function, source, name, arguments) ⇒ Function

Returns a new instance of Function.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/twostroke/runtime/types/function.rb', line 37

def initialize(function, source, name, arguments)
  @function = function
  @source = source
  @name = name
  @arguments = arguments
  # setting @_class to Function's constructor would result in a stack overflow,
  # so we'll set it to nil and patch things up after @@constructor_function has
  # been set
  @_class = nil unless defined?(@@constructor_function)
  super()
  @prototype = nil
  proto = Object.new
  proto.construct _class: self
  put "prototype", proto
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def arguments
  @arguments
end

#functionObject (readonly)

Returns the value of attribute function.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def function
  @function
end

#inherits_caller_thisObject

Returns the value of attribute inherits_caller_this.



36
37
38
# File 'lib/twostroke/runtime/types/function.rb', line 36

def inherits_caller_this
  @inherits_caller_this
end

#nameObject (readonly)

Returns the value of attribute name.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def name
  @name
end

#sourceObject (readonly)

Returns the value of attribute source.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def source
  @source
end

Class Method Details

.constructor_functionObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/twostroke/runtime/types/function.rb', line 3

def self.constructor_function
  unless defined?(@@constructor_function)
    @@constructor_function = nil # lock the Function constructor out from here...
    @@created_funcs = 0
    @@constructor_function = Function.new(->(scope, this, args) {
      formal_parameters = (args.size > 1 ? args[0...-1] : []).map { |a| Twostroke::Runtime::Types.to_string(a).string }
      src = Twostroke::Runtime::Types.to_string(args[-1] || Undefined.new).string
      
      parser = Twostroke::Parser.new(Twostroke::Lexer.new(src))
      parser.parse

      @@created_funcs += 1
      fun_ast = Twostroke::AST::Function.new name: "anonymous", arguments: formal_parameters, statements: parser.statements
      compiler = Twostroke::Compiler::TSASM.new [fun_ast], "runtime_created_#{@@created_funcs}_"
      compiler.compile
      
      vm = scope.global_scope.vm
      compiler.bytecode.each do |k,v|
        vm.bytecode[k] = v
      end
      
      global_scope = vm.global_scope
      fun = Function.new(->(_scope, _this, _args) {
        Twostroke::Runtime::VM::Frame.new(vm, :"runtime_created_#{@@created_funcs}_fn_1", fun).execute(global_scope, _this, _args)
      }, src, "anonymous", formal_parameters)
    }, nil, "Function", [])
    @@constructor_function.proto_put "constructor", @@constructor_function
    @@constructor_function._class = @@constructor_function
  end
  @@constructor_function
end

Instance Method Details

#call(upper_scope, this, args) ⇒ Object



76
77
78
79
80
81
82
83
84
# File 'lib/twostroke/runtime/types/function.rb', line 76

def call(upper_scope, this, args)
  retn_val = function.(upper_scope, this || upper_scope.global_scope.root_object, args)
  # prevent non-Value objects being returned to javascript
  if retn_val.is_a? Value
    retn_val
  else
    Undefined.new
  end
end

#has_instance(obj) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/twostroke/runtime/types/function.rb', line 61

def has_instance(obj)
  return false unless obj.is_a? Object
  o = get "prototype"
  Twostroke::Runtime::Lib.throw_type_error "Function prototype not an object" unless o.is_a? Object
  loop do
    obj = obj.prototype
    return false unless obj.is_a?(Object)
    return true if obj == o
  end
end

#prototypeObject



57
58
59
# File 'lib/twostroke/runtime/types/function.rb', line 57

def prototype
  @prototype ||= Function.constructor_function.get("prototype") if Function.constructor_function
end

#to_rubyObject



53
54
55
# File 'lib/twostroke/runtime/types/function.rb', line 53

def to_ruby
  ->(this, *args) { call(nil, this, args.map(&Twostroke::Runtime::Types.method(:marshal))).to_ruby }
end

#typeofObject



72
73
74
# File 'lib/twostroke/runtime/types/function.rb', line 72

def typeof
  "function"
end