class XfOOrth::VirtualMachine

The virtual machine is the heart of the fOOrth language system that is used to facilitate the stack oriented processing of data and language elements.

Alias support methods in the VirtualMachine class.

Stub support methods in the VirtualMachine class.

Constants

ALLOWED_ALIAS_TYPES
PROC_VAL

The procedure used for procedure instance values

PROC_VAR

The procedure used for procedure instance variables

Attributes

context[R]

The current execution/compile context.

data[R]

The thread data associated with this virtual machine.

data_stack[RW]

The fOOrth data stack. This is the primary means used to hold data for processing.

debug[RW]

Set true for verbose compiler play-by-plays and detailed error reports.

fiber[RW]

The currently active fiber, if any.

name[R]

The descriptive name of this virtual machine.

parens[RW]

The level of comment nesting.

parser[R]

The current compiler parser.

quotes[RW]

The level of quote nesting.

show_stack[RW]

Set true to print out the data stack after every interactive line is processed.

start_time[RW]

The fOOrth timer anchor point. Used to assist in benchmarking etc.

Public Class Methods

create_foorth_subclass(_name) click to toggle source

Create a new fOOrth subclass of this class. This is not allowed for the VirtualMachine class so this stub merely raises an exception.

# File lib/fOOrth/core/virtual_machine.rb, line 21
def create_foorth_subclass(_name)
  error "F13: Forbidden operation: VirtualMachine .class: "
end
new(name='-') click to toggle source

Create an new instance of a fOOrth virtual machine
Parameters:

  • name - An optional string that describes this virtual machine instance.


Note

  • A XfOOrthError will be raised if an attempt is made to create more than one virtual machine on a thread.

# File lib/fOOrth/initialize.rb, line 38
def initialize(name='-')
  @name, @debug, @show_stack, @data = name, false, false, {}

  #Bring the major sub-systems to a known state.
  self.reset.connect_vm_to_thread
end
vm(name='-') click to toggle source

Get or create a virtual machine for this thread.
Paramters:

  • name - The name of the virtual machine, if one is created. If a virtual machine already exists for this thread, this parameter is ignored.


Note: Non-intuitive code.

  • VitualMachine.new connects to the thread, setting up Thread.current[:vm] as a side-effect. Thus it is not done here.

# File lib/fOOrth/initialize.rb, line 16
def self.vm(name='-')
  Thread.current[:vm] || VirtualMachine.new(name)
end

Public Instance Methods

<<(text) click to toggle source

Append text to the compile buffer.

# File lib/fOOrth/compiler.rb, line 48
def <<(text)
  dbg_puts "  Append=#{text.inspect}"
  @buffer << text
rescue NoMethodError
  error "F14: The current mode does not allow code to be appended."
end
add_to_hash() click to toggle source

Add the key and value to the hash being constructed.

# File lib/fOOrth/interpreter/add_to_hash.rb, line 10
def add_to_hash
  key, value = popm(2)
  peek(1)[key] = value
end
begin_compile_mode(ctrl, defs={}, &action) click to toggle source

Start compiling a fOOrth definition. This is used to get things going by the various compiling words like ':', '::', ':::', etc.
Parameters:

  • ctrl - The control symbol that started the compilation.

  • action - A block to be executed when the compilation is done.


Note:

  • Adds a nested context level to be un-nested at a later point.

# File lib/fOOrth/compiler/modes/compiled.rb, line 15
def begin_compile_mode(ctrl, defs={}, &action)
  dbg_puts "  begin_compile_mode"
  @context.check_set(:mode, [:execute])
  @context = Context.new(@context, mode: :compile, ctrl: ctrl, action: action)
  @context.merge(defs)
  @buffer = ''
end
buffer_valid?() click to toggle source

Is the buffer valid?

# File lib/fOOrth/compiler.rb, line 56
def buffer_valid?
  @buffer.is_a?(String)
end
check_deferred_mode(text, ctrls) click to toggle source

Verify the deferred execution state. This are used by words that work within a word grouping like else or while.
Parameters:

  • text - Some text to append to the buffer before bundling it up.

  • ctrls - An array of control symbols that could have started the deferral.

# File lib/fOOrth/compiler/modes/deferred.rb, line 35
def check_deferred_mode(text, ctrls)
  @context.check_set(:ctrl, ctrls)
  self << text
end
clear_cast() click to toggle source

Clear the method cast

# File lib/fOOrth/compiler/cast.rb, line 16
def clear_cast
  @cast = nil
end
compiler_reset() click to toggle source

Return the compiler to a known state.

# File lib/fOOrth/compiler.rb, line 39
def compiler_reset
  @buffer = @parser = nil
  @quotes = @parens = 0
  clear_cast
  @context = Context.new(nil, vm: self, mode: :execute)
  self
end
connect_vm_to_thread() click to toggle source

Connect the vm to a thread variable.

# File lib/fOOrth/initialize.rb, line 70
def connect_vm_to_thread
  #Check for duplicates.
  current = Thread.current
  error "F91: Only one virtual machine allowed per thread" if current[:vm]

  #This virtual machine is associated with this thread.
  current[:vm] = self
  @start_time  = Time.now

  self
end
console() click to toggle source

The current system console object. Gets the current console object only creating one if somebody asks for one.
Note

  • This is to be the sole occurrence of @_private_console

# File lib/fOOrth/compiler.rb, line 22
def console
  @_private_console ||= Console.new
end
create_exclusive_alias(new_name) click to toggle source

Create an exclusive method alias

# File lib/fOOrth/library/alias_library.rb, line 62
def create_exclusive_alias(new_name)
  old_name, target = popm(2)

  old_spec = get_old_exclusive_spec(target, old_name)

  target.create_exclusive_method(new_name,
                                 get_alias_type(old_spec, new_name),
                                 old_spec.tags,
                                 &old_spec.does)
  clear_cast
end
create_exclusive_stub(name) click to toggle source

Create an exclusive method stub

# File lib/fOOrth/library/stubs_library.rb, line 39
def create_exclusive_stub(name)
  target = pop
  type = XfOOrth.name_to_type(name, self)
  XfOOrth.validate_type(self, type, name)
  target.create_exclusive_method(name, type, [:stub])
  clear_cast
end
create_shared_alias(new_name) click to toggle source

Create a shared method alias

# File lib/fOOrth/library/alias_library.rb, line 45
def create_shared_alias(new_name)
  old_name, target = popm(2)

  unless target.is_a?(Class)
    error "F13: The target of .alias: must be a class"
  end

  old_spec = get_old_shared_spec(target, old_name)

  target.create_shared_method(new_name,
                              get_alias_type(old_spec, new_name),
                              old_spec.tags,
                              &old_spec.does)
  clear_cast
end
create_shared_stub(name) click to toggle source

Create a shared method stub

# File lib/fOOrth/library/stubs_library.rb, line 27
def create_shared_stub(name)
  unless (target = pop).is_a?(Class)
    error "F13: The target of .stub: must be a class"
  end

  type = XfOOrth.name_to_type(name, self)
  XfOOrth.validate_type(self, type, name)
  target.create_shared_method(name, type, [:stub])
  clear_cast
end
create_word_alias(new_name) click to toggle source

Create a virtual machine word method alias.

# File lib/fOOrth/library/alias_library.rb, line 33
def create_word_alias(new_name)
  old_name, target = pop, self.class

  old_spec = get_old_shared_spec(target, old_name)

  target.create_shared_method(new_name,
                              old_spec.class,
                              old_spec.tags,
                              &old_spec.does)
end
dbg_puts(*args) click to toggle source

Send out debug info to the fOOrth debug port if debug is enabled.

# File lib/fOOrth/debug/dbg_puts.rb, line 10
def dbg_puts(*args)
  $foorth_dbg.puts(*args) if debug
end
delayed_compile_mode(start) click to toggle source

Enter a delayed compile mode in which compilation is delayed till a later time.

# File lib/fOOrth/compiler/modes/delayed.rb, line 10
def delayed_compile_mode(start)
  dbg_puts "  begin_delayed_compile_mode"

  buffer = do_delayed_compile_mode(start)

  dbg_puts "  Append=#{buffer}"
  @buffer << buffer
  dbg_puts "  end_delayed_compile_mode"
end
display_abort(exception) click to toggle source

Display the diagnostic data required for a language abort error.
Parameters:

  • exception - The exception object that required the system abort or a string describing the error that was encountered.

# File lib/fOOrth/debug/display_abort.rb, line 13
def display_abort(exception)
  puts "\n#{exception.foorth_message}"

  if debug
    puts "Data Stack Contents: #{data_stack.inspect}"

    puts "\nInternal Backtrace Dump:"
    puts
    puts exception.backtrace
    puts
  end

  reset
end
do_delayed_compile_mode(start) click to toggle source

The worker bee for delayed_compile_mode.
Endemic Code Smells

  • :reek:FeatureEnvy – false positive

# File lib/fOOrth/compiler/modes/delayed.rb, line 23
def do_delayed_compile_mode(start)
  buffer, depth = start + ' ', 1

  while depth > 0
    if (word = parser.get_word_or_string)
      buffer << word + ' '
      depth += 1 if [':', '!:', '.:', '.::'].include?(word)
      depth -= 1 if word == ';'
    else
      error "F12: Error, Invalid compile nesting."
    end
  end

  "vm.process_string(#{buffer.foorth_embed}); "
end
end_compile_mode(ctrls) click to toggle source

Finish compiling a fOOrth definition. This is used to wrap things up, mostly by the semi-colon ';' word.
Parameters:

  • ctrls - an array of the allowed set of control values.


Returns:

  • The value of the action block.


Note:

  • Un-nests a context level.

# File lib/fOOrth/compiler/modes/compiled.rb, line 31
def end_compile_mode(ctrls)
  @context.check_set(:ctrl, ctrls)
  source, @buffer = "lambda {|vm| #{@buffer} }", nil
  result = instance_exec(self, source, @context.tags, &@context[:action])
  @context = @context.previous
  dbg_puts "  end_compile_mode"
  result
end
execute_mode?() click to toggle source

Check to see if the virtual machine is in execute mode.

# File lib/fOOrth/compiler/modes.rb, line 27
def execute_mode?
  @context[:mode] == :execute
end
foorth_copy(name) click to toggle source

Create a copy of a donor vm instance.
Parameters:

  • name - An optional string that describes this virtual machine instance.

# File lib/fOOrth/initialize.rb, line 48
def foorth_copy(name)
  copy = self.clone
  copy.reinitialize(name)
  copy
end
foorth_name() click to toggle source

The name of the virtual machine instance

# File lib/fOOrth/core/virtual_machine.rb, line 10
def foorth_name
  "#{self.class.foorth_name} instance <#{@name}>"
end
generate_code(token, word) click to toggle source

Finally generate some code!
Parameters:

  • token - The token to receive the generated code.

  • word - The text of the word.

# File lib/fOOrth/compiler/process/generate.rb, line 13
def generate_code(token, word)
  if (spec = @context.map_with_defaults(word))
    token.add(spec.builds, spec.tags)
  elsif (value = word.to_foorth_n)
    token.add("vm.push(#{value.foorth_embed}); ", [:numeric])
  else
    error "F10: ?#{word}?"
  end
end
get_cast() click to toggle source

Get the method cast and clear it.

# File lib/fOOrth/compiler/cast.rb, line 33
def get_cast
  @cast
end
get_info() click to toggle source

Get introspection info.

# File lib/fOOrth/library/introspection/vm.rb, line 10
def get_info
  results = get_basic_vm_info
  get_instance_variable_info(results)
  get_vm_thread_data_info(results)
  get_exclusive_method_info(results, "Exclusive")

  results
end
get_token() click to toggle source

Get the next token structure from the source code or nil if none can be found.
Returns

  • A Token structure or nil.

# File lib/fOOrth/compiler/process/get_token.rb, line 13
def get_token
  return nil unless (word = parser.get_word)

  token = Token.new
  string_parms(token, word) || procedure_parms(token, word)
  generate_code(token, word)
  token
end
interpreter_reset() click to toggle source

Reset the state of the fOOrth inner interpreter.

# File lib/fOOrth/interpreter.rb, line 18
def interpreter_reset
  @data_stack = Array.new
  self
end
nest_mode(text, ctrl) click to toggle source

Enter a nested context without altering the current mode.
Parameters:

  • text - Some text to append associated with the nested state.

  • ctrl - The control symbol that started the nested context.


Note:

  • Adds a nested context level to be un-nested at a later point.

# File lib/fOOrth/compiler/modes/nested.rb, line 14
def nest_mode(text, ctrl)
  dbg_puts "  nest_context"
  @context = Context.new(@context, ctrl: ctrl)
  process_text(text)
end
peek(index=1) click to toggle source

Read an entry from the data stack without modify that stack.
Parameters:

  • index - The (optional) entry to be retrieved. 1 corresponds to the “top” of the stack, 2 the next element, etc. This parameter defaults to 1.


Returns:

  • The element specified from the data stack.


Note:

  • Attempting to access an element deeper than the number of elements on the stack will fail with an XfOOrthError exception.

# File lib/fOOrth/interpreter/data_stack.rb, line 72
def peek(index=1)
  unless @data_stack.length >= index && index > 0
    error "F30: Data Stack Underflow: peek"
  end

  @data_stack[-index]
end
peek?(index=1) click to toggle source

Read an entry from the data stack as a boolean without modify that stack.
Parameters:

  • index - The (optional) entry to be retrieved. 1 corresponds to the “top” of the stack, 2 the next element, etc. This parameter defaults to 1.


Returns:

  • The element specified from the data stack as a boolean.


Note:

  • Attempting to access an element deeper than the number of elements on the stack will fail with an XfOOrthError exception.

# File lib/fOOrth/interpreter/data_stack.rb, line 99
def peek?(index=1)
  peek(index).to_foorth_b
end
poke(datum) click to toggle source

Overwrite the TOS with the supplied data.
Parameters:

  • datum - The data to be placed in the data stack.


Note:

  • Attempting to poke an empty stack will fail with an XfOOrthError exception.

# File lib/fOOrth/interpreter/data_stack.rb, line 85
def poke(datum)
  error "F30: Data Stack Underflow: poke" if @data_stack.empty?
  @data_stack[-1] = datum
end
pop() click to toggle source

Remove the “top” entry from the data stack.
Returns:

  • The “top” element of the data stack.


Note:

  • If the stack is empty this will raise an XfOOrthError exception.

# File lib/fOOrth/interpreter/data_stack.rb, line 31
def pop
  error "F30: Data Stack Underflow: pop" if @data_stack.empty?
  @data_stack.pop
end
pop?() click to toggle source

Remove the “top” entry from the data stack as a boolean.
Returns:

  • The “top” element of the data stack as a boolean


Note:

  • If the stack is empty this will raise an XfOOrthError exception.

# File lib/fOOrth/interpreter/data_stack.rb, line 58
def pop?
  pop.to_foorth_b
end
popm(count) click to toggle source

Remove multiple entries from the “top” of the data stack.
Parameters:

  • count - the number of elements to be returned.


Returns:

  • An array containing the “top” count elements of the data stack.


Note:

  • Raises an XfOOrthError exception if the stack has too few data.

# File lib/fOOrth/interpreter/data_stack.rb, line 43
def popm(count)
  begin
    error "F30: Data Stack Underflow: popm" if @data_stack.length < count
    @data_stack.pop(count)
  rescue
    @data_stack = []
    raise
  end
end
process_console() click to toggle source

Execute code from the interactive console.

# File lib/fOOrth/compiler.rb, line 61
def process_console
  process(console)
ensure
  console.flush
end
process_file(name) click to toggle source

Execute a file of code.

# File lib/fOOrth/compiler.rb, line 73
def process_file(name)
  source = FileSource.new(name)

  begin
    process(source)
  ensure
    source.close
  end
end
process_string(str) click to toggle source

Execute a string of code.

# File lib/fOOrth/compiler.rb, line 68
def process_string(str)
  process(StringSource.new(str))
end
process_text(text) click to toggle source

Depending on the mode, process the text source code.
Parameters:

  • text - Some text to be executed or deferred.

# File lib/fOOrth/compiler/modes.rb, line 17
def process_text(text)
  if execute_mode?
    dbg_puts "  Code=#{text.inspect}"
    @context.target.instance_exec(self, &eval("lambda {|vm| #{text} }"))
  else
    self << text
  end
end
push(datum) click to toggle source

Add an entry to the data stack.
Parameters:

  • datum - The data to be added to the data stack.

# File lib/fOOrth/interpreter/data_stack.rb, line 15
def push(datum)
  @data_stack << datum
end
pushm(datum) click to toggle source

Add some entries to the data stack.
Parameters:

  • datum - An array of data to be mass added to the data stack.

# File lib/fOOrth/interpreter/data_stack.rb, line 22
def pushm(datum)
  @data_stack += datum
end
reinitialize(name) click to toggle source

Get the vm ready for operation
Parameters:

  • name - A string that describes this virtual machine instance.

# File lib/fOOrth/initialize.rb, line 57
def reinitialize(name)
  @data_stack = @data_stack.clone
  @name       = name
  @data       = @data.full_clone
end
reset() click to toggle source

Reset the interpreter and the compiler.

# File lib/fOOrth/initialize.rb, line 64
def reset
  interpreter_reset
  compiler_reset
end
resume_buffered_mode(ctrls) click to toggle source

While compiling and compiling is suspended, resume normal compiling.
Parameters:

  • ctrls - An array of control symbols that could have suspended the compilation.


Note:

  • Un-nests a context level.

# File lib/fOOrth/compiler/modes/suspend.rb, line 29
def resume_buffered_mode(ctrls)
  dbg_puts "  resume_buffered_mode"
  @context.check_set(:ctrl, ctrls)
  @context = @context.previous
end
resume_execute_mode(text, ctrls) click to toggle source

If execution was previously deferred, resume the previous mode. This is used in words that close off a block action like then, loop, or repeat.
Parameters:

  • text - Some text to append to the buffer before bundling it up.

  • ctrls - An array of control symbols that could have started the deferral.


Note:

  • Un-nests a context level.

# File lib/fOOrth/compiler/modes/deferred.rb, line 47
def resume_execute_mode(text, ctrls)
  dbg_puts "  resume_execute_mode"
  check_deferred_mode(text, ctrls)
  @context = @context.previous

  if @context[:mode] == :execute
    source, @buffer = "lambda {|vm| #{@buffer} }", nil
    instance_exec(self, &eval(source))
  end
end
set_cast(spec) click to toggle source

Set the method cast.

# File lib/fOOrth/compiler/cast.rb, line 10
def set_cast(spec)
  error "F12: Multiple methods casts detected." if @cast
  @cast = spec
end
squash() click to toggle source

Compress the entire data stack into a single entry.

# File lib/fOOrth/interpreter/squash.rb, line 10
def squash
  @data_stack = [@data_stack]
end
string_parms(token, word) click to toggle source

Process optional string parameters.
Parameters:

  • token - The token to receive the generated code.

  • word - The text of the word.

# File lib/fOOrth/compiler/process/string.rb, line 13
def string_parms(token, word)
  source = parser.source

  if word.end_with?('"')
    string_value = parser.get_string.foorth_embed

    if source.peek == '*'
      source.get
      token.add("vm.push(StringBuffer.new(#{string_value})); ", [:string])
    else
      token.add("vm.push(#{string_value}.freeze); ", [:string])
    end
  end
end
suspend_buffered_mode(ctrl) click to toggle source

While compiling, suspend compiling so that some code may be executed.
Parameters:

  • ctrl - The control symbol that suspended the compilation.


Note:

  • Adds a nested context level to be un-nested at a later point.

# File lib/fOOrth/compiler/modes/suspend.rb, line 13
def suspend_buffered_mode(ctrl)
  dbg_puts "  suspend_buffered_mode"

  unless buffer_valid?
    error "F14: The #{ctrl} method is not available in execute mode."
  end

  @context = Context.new(@context, mode: :execute, ctrl: ctrl)
end
suspend_execute_mode(text, ctrl) click to toggle source

Enter a mode where execution is deferred. If currently in :execute mode, enter :deferred mode else the mode is unchanged. This is used by words that need to group words together to work like if, do, and begin.
Parameters:

  • text - Some text to append to the buffer before proceeding.

  • ctrl - The control symbol that started the deferral.


Notes:

  • Adds a nested context level to be un-nested at a later point.

  • Enters deferred mode only if currently in execute mode. Otherwise continues in the current mode.

# File lib/fOOrth/compiler/modes/deferred.rb, line 18
def suspend_execute_mode(text, ctrl)
  dbg_puts "  suspend_execute_mode"
  @context = Context.new(@context, ctrl: ctrl)

  if execute_mode?
    @context[:mode] = :deferred
    @buffer = ''
  end

  self << text
end
swap_pop() click to toggle source

A special operation to support dyadic operators. Swap then pop.
Returns:

  • The second element from the data stack.


Note:

  • If the stack has less than 2 elements, this will raise an XfOOrthError exception.

# File lib/fOOrth/interpreter/data_stack.rb, line 109
def swap_pop
  begin
    unless @data_stack.length >= 2
      error "F30: Data Stack Underflow: swap_pop"
    end

    nos, tos = @data_stack.pop(2)
    @data_stack << tos
    nos
  rescue
    @data_stack = []
    raise
  end
end
unnest_mode(text, ctrls) click to toggle source

Leave a nested context without altering the current mode.
Parameters:

  • text - Some text to append associated with the nested state.

  • ctrls - An array of control symbols that could have started the nest.


Note:

  • Removes a nested context level.

# File lib/fOOrth/compiler/modes/nested.rb, line 26
def unnest_mode(text, ctrls)
  dbg_puts "  unnest_context"
  @context.check_set(:ctrl, ctrls)
  @context = @context.previous
  process_text(text) if text
end
unsquash() click to toggle source

Compress all the added entries into a single entry and revive the previous contents of the data stack.

# File lib/fOOrth/interpreter/squash.rb, line 16
def unsquash
  previous = @data_stack[0]
  data = @data_stack[1..-1]
  @data_stack = previous
  push(data)
end
verify_cast(allowed) click to toggle source

Verify the method cast

# File lib/fOOrth/compiler/cast.rb, line 21
def verify_cast(allowed)
  if @cast && !allowed.include?(@cast)
    error "F13: Cast of #{@cast.foorth_class_name} not allowed."
  end
end
verify_casts_cleared() click to toggle source

Make sure there are no dangling casts.

# File lib/fOOrth/compiler/cast.rb, line 28
def verify_casts_cleared
  error "F12: Dangling method cast detected." if @cast
end
version() click to toggle source

Get the version string for this virtual machine.
Endemic Code Smells

  • :reek:UtilityFunction

# File lib/fOOrth.rb, line 49
def version
  XfOOrth.version
end
vm_do(jloop = [0, 0, 0]) { |iloop, jloop| ... } click to toggle source

The runtime implementation of the “do” word.
Parameters:

  • jloop - An optional outer loop value.

  • block - A block of code to be executed as the do loop body.


Block Parameters:

  • iloop - The stack frame of the current loop counter. This corresponds to the fOOrth 'i' value.

  • jloop - The stack frame of any containing loop counter. This corresponds to the fOOrth 'j' value. If there is no containing loop, this will always be a zero frame ie: [0, 0, 0].


Note:

  • Nested loops must be in the same compiler context in order to use this mechanism. Otherwise, loop index counters must be passed in explicitly.


Endemic Code Smells

  • :reek:FeatureEnvy – false positive

# File lib/fOOrth/interpreter/do_loop.rb, line 24
def vm_do(jloop = [0, 0, 0], &block)
  #Pop the start and ending values from the stack.
  start_index, end_index = popm(2)

  #Construct the loop data frame.
  iloop = [start_index, end_index - 1, start_index + end_index - 1]

  #Loop until done!
  while iloop[0] <= iloop[1]
    #Yield to the loop.
    yield iloop, jloop
  end
end
vm_do_increment() click to toggle source

The runtime implementation of the “+loop” word.

# File lib/fOOrth/interpreter/do_loop.rb, line 39
def vm_do_increment
  inc_raw = self.pop

  unless (inc_value = inc_raw.to_foorth_n)
    error "F40: Cannot convert a #{inc_raw.foorth_name} to a Numeric instance"
  end

  if inc_value > 0
    inc_value
  else
    error "F41: Invalid loop increment value: #{inc_value}"
  end
end

Private Instance Methods

close_procedure_literal() click to toggle source

Handle the closing of a procedure literal.

# File lib/fOOrth/compiler/process/procedure.rb, line 91
def close_procedure_literal
  unnest_mode(nil, [:procedure])
end
due_process() click to toggle source

The actual work of processing source code.

# File lib/fOOrth/compiler/process.rb, line 30
def due_process
  while (token = get_token)
    due_token(token)
  end
end
due_token(token) click to toggle source

Finally, process the taken.

# File lib/fOOrth/compiler/process.rb, line 37
def due_token(token)
  dbg_puts token.to_s
  code = token.code

  if execute_mode? || token.has_tag?(:immediate)
    @context.target.instance_exec(self, &eval("lambda {|vm| #{code} }"))
  else
    self << code
  end
end
get_alias_type(old_spec, new_name) click to toggle source

Get the type of the aliased method.

# File lib/fOOrth/library/alias_library.rb, line 106
def get_alias_type(old_spec, new_name)
  old_type = old_spec.class
  new_type = XfOOrth.name_to_type(new_name, self)
  old_desc, new_desc = old_type.foorth_name, new_type.foorth_name

  unless (allowed = ALLOWED_ALIAS_TYPES[old_type])
    error "F13: A #{old_desc} method may not be aliased."
  end

  unless allowed.include?(new_type)
    error "F13: A #{old_desc} method may not be aliased as a #{new_desc}"
  end

  XfOOrth.validate_type(self, new_type, new_name)

  new_type
end
get_basic_vm_info() click to toggle source

Get the vm basic stuff first.

# File lib/fOOrth/library/introspection/vm.rb, line 22
def get_basic_vm_info
  results = [["Name",    foorth_name],
             ["Ruby",    self.to_s],
             ["Stack",   @data_stack.inspect],
             ["Nesting", @context.depth],
             ["Quotes",  @quotes],
             ["Debug",   @debug],
             ["Show",    @show_stack],
             ["Start",   @start_time]]

  if (source  = @parser && @parser.source)
    results << ["Source", source.source_name]
    results << ["Buffer", source.read_buffer.inspect]
  end

  results
end
get_old_exclusive_spec(target, old_name) click to toggle source

Get the exclusive specification of the original method.

# File lib/fOOrth/library/alias_library.rb, line 88
def get_old_exclusive_spec(target, old_name)
  old_symbol = get_old_symbol(old_name)

  unless (old_spec = target.map_foorth_exclusive(old_symbol))
    f20_error(target, old_name, old_symbol)
  end

  old_spec
end
get_old_shared_spec(target, old_name) click to toggle source

Get the shared specification of the original method.

# File lib/fOOrth/library/alias_library.rb, line 77
def get_old_shared_spec(target, old_name)
  old_symbol = get_old_symbol(old_name)

  unless (old_spec = target.map_foorth_shared(old_symbol))
    f20_error(target, old_name, old_symbol)
  end

  old_spec
end
get_old_symbol(old_name) click to toggle source

Get the symbol of the old method.

# File lib/fOOrth/library/alias_library.rb, line 99
def get_old_symbol(old_name)
  old_symbol = XfOOrth::SymbolMap.map(old_name)
  error "F10: ?#{old_name}?" unless old_symbol
  old_symbol
end
get_procedure_literal() click to toggle source

Extract a procedure literal from the source code.

# File lib/fOOrth/compiler/process/procedure.rb, line 22
def get_procedure_literal
  save, @buffer  = @buffer, ""
  open_procedure_literal

  begin
    token = get_procedure_token
    due_token(token)
  end until token.has_tag?(:end)

  close_procedure_literal
  (_, @buffer = @buffer, save)[0]
end
get_procedure_token() click to toggle source

Get a token for the procedure literal.

# File lib/fOOrth/compiler/process/procedure.rb, line 96
def get_procedure_token
  error "F12: Error, Invalid nesting." unless (token = get_token)
  token
end
get_vm_thread_data_info(results) click to toggle source

Get the thread data info.

# File lib/fOOrth/library/introspection/vm.rb, line 41
def get_vm_thread_data_info(results)
  unless @data.empty?
    results.concat([["", ""], ["Data", "Thread"], ["", ""]])

    @data
      .keys
      .map{|symbol| [SymbolMap.unmap(symbol), symbol]}
      .sort{|first, second| first[0] <=> second[0]}
      .map{|name, symbol| [name, @data[symbol]]}
      .each do |name, value|
        results << [name, value.inspect]
      end
  end
end
open_procedure_literal() click to toggle source

Handle the opening of a procedure literal.

# File lib/fOOrth/compiler/process/procedure.rb, line 72
def open_procedure_literal
  suspend_execute_mode("vm.push(lambda {|vm, val=nil, idx=nil| ", :procedure)

  #Support for the standard procedure parameters.
  context.create_local_method('v',  MacroSpec, [:macro, "vm.push(val); "])
  context.create_local_method('x',  MacroSpec, [:macro, "vm.push(idx); "])

  #Support for local data.
  context.create_local_method('var:', LocalSpec, [:immediate], &Local_Var_Action)
  context.create_local_method('val:', LocalSpec, [:immediate], &Local_Val_Action)

  #Support for procedure instance data.
  context.create_local_method('var@:', LocalSpec, [:immediate], &PROC_VAR)
  context.create_local_method('val@:', LocalSpec, [:immediate], &PROC_VAL)

  context.create_local_method('}}', MacroSpec, [:macro, :end,     "}); "])
end
procedure_parms(token, word) click to toggle source

Process optional string parameters.
Parameters:

  • token - The token to receive the generated code.

  • word - The text of the word.

# File lib/fOOrth/compiler/process/procedure.rb, line 15
def procedure_parms(token, word)
  if word.end_with?('{{')
    token.add(get_procedure_literal, [:procedure])
  end
end
process(source) click to toggle source

Process the source code provided by the source parameter.
Parameters:

# File lib/fOOrth/compiler/process.rb, line 19
def process(source)
  save, @parser, start_depth = @parser, Parser.new(source), @context.depth

  due_process
  @context.check_depth(start_depth)
  verify_casts_cleared

  @parser = save
end