class TracLang::Dispatch

Class to dispatch TRAC commands to the proper code. Also stores the following options needed to run TRAC:

trace

Determines whether to display TRAC commands before executing them

meta

Meta character used to signal the end of input

savedir

Directory to save blocks to and load them from

Attributes

table[RW]

Dispatch table. All basic TRAC commands are stored in the dispatch table. This is done instead of methods to prevent someone from inadvertently (or on purpose) calling a Ruby internal method instead of a TRAC command.

meta[R]

Meta character to end input. When the Executor is reading from a file, it will only pass the string on to the Parser after a meta character is received. Also, the TRAC #(RS) command will only return after a meta character is pressed.

save_dir[RW]

Directory that blocks are read from and written to.

trace[RW]

Flag for whether trace is on or off. When trace is on, each time an Expression is parsed for execution, the Executor will display the Expression and wait for user input. If the user presses enter, TRAC proceeds as normal. If any other key is pressed, the Executor is reset.

Public Class Methods

dispatch_form(sym, type, pos = -1) click to toggle source

Defines mapping from dispatch command to Form method. The parameters are:

sym

Method name in Form to map to.

type

One of

  • :returning_empty To return an empty string.

  • :returning_value To return the value returned from the Form method.

  • :rescuing_eos To rescue in case EndOfStringError is raised.

pos

Used when type is :rescuing_eos. Index of argument that is returned in case EndOfStringError is raised.

The following mnemonics are mapped to Form methods:

:ss

Segment String. Mapped to Form.segment_string.

:cr

Call Return. Mapped to Form.call_return.

:cl

Call Lookup. Mapped to Form.call_lookup.

:cc

Call Character. Mapped to Form.call_character.

:cs

Call Segment. Mapped to Form.call_segment.

:cn

Call N Characters. Mapped to Form.call_n.

:in

In String. Mapped to Form.in_neutral.

# File lib/trac_lang/dispatch.rb, line 265
def self.dispatch_form(sym, type, pos = -1)
  table[mnemonic(sym)] = Proc.new do |name = '', *args|
    f = @root.fetch(name)
    if !f 
      return_empty
    else
      case type
      when :returning_empty
        f.send(sym, *args)
        return_empty
      when :returning_value
        return_value(f.send(sym, *args))
      when :rescuing_eos_at
        eos_result = args.slice!(pos) || ''
        begin
          return_value(f.send(sym, *args))
        rescue TracLang::Form::EndOfStringError
          return_force(eos_result)
        end
      end
    end
  end
end
dispatch_to_decimal(symbol) click to toggle source

Maps a mnemonic to a Decimal operation. The following are mapped:

:ad

Add. Maps to Decimal.+.

:su

Subtract. Maps to Decimal.-.

:ml

Maps to Decimal.*.

:dv

Maps to Decimal./. If a ZeroDivisionError is detected, the overflow string is forced to output.

# File lib/trac_lang/dispatch.rb, line 365
def self.dispatch_to_decimal(symbol)
  Proc.new do |s1 = '', s2 = '', overflow = ''|
    d1 = Decimal.new(s1)
    d2 = Decimal.new(s2)
    begin
      return_value(d1.send(symbol, d2).to_s)
    rescue ZeroDivisionError
      return_force(overflow)
    end
  end
end
dispatch_to_mixed(sym) click to toggle source

Maps a mnemonic to a mixed Octal and Decimal operation. The following are mapped:

:bs

Bit Shift. Mapped to Octal.shift.

:br

Bit Rotate. Mapped to Octal.rotate.

# File lib/trac_lang/dispatch.rb, line 404
def self.dispatch_to_mixed(sym)
  Proc.new do |oct = '', dec = ''|
    if dec.empty? || oct.empty?
      return_empty
    else
      o1 = Octal.new(oct)
      d1 = Decimal.new(dec)
      return_value(o1.send(sym, d1).to_s)
    end
  end
end
dispatch_to_octal(symbol) click to toggle source

Maps a mnemonic to a Octal operation. The following are mapped:

:bu

Bit Union. Mapped to Octal.|.

:bi

Bit Intersection. Mapped to Octal.&.

# File lib/trac_lang/dispatch.rb, line 385
def self.dispatch_to_octal(symbol)
  Proc.new do |s1 = '', s2 = ''|
    o1 = Octal.new(s1)
    o2 = Octal.new(s2)
    return_value(o1.send(symbol, o2).to_s)
  end
end
mnemonic(name) click to toggle source

Determines the TRAC mnemonic name from the given method name. This is used to map TRAC names to Form methods.

# File lib/trac_lang/dispatch.rb, line 131
def self.mnemonic(name)
  name.to_s.split('_').map {|w| w[0]}.join.to_sym
end
new(**options) click to toggle source

Initializes environment for TRAC with a set of options. Options are:

bindings

Bindings to use

trace

Turn trace on or off

savedir

Directory that blocks are written to and read from.

# File lib/trac_lang/dispatch.rb, line 167
def initialize(**options)
  @root = options[:bindings] || Bindings.new
  @trace = options[:trace] || false
  @savedir = options[:savedir] || './'
  @meta = "'"
end
on(sym) click to toggle source

Defines a TRAC command to be added to the dispatch table. The following commands are defined.


System Commands

on :hl

Halt. Halts the TRAC processor.

on :tn

Trace On. While trace is on, each Expression to be executed will be displayed to the user first. If the user presses return, the Expression will be executed. If any other key is pressed, the active string will be cleared and the idle string will be reloaded.

on :tf

Trace Off. When trace is off, execution proceeds as normal.

on :pf do |name = ''|

Print Form. Prints the form with the given name on the console. The form text, segments, and form pointer will all be displayed.


Basic Commands

on :ds do |name = '', value = ''|

Define String. Creates a new Form with the given name and value, and stores it in the current set of bindings.

on :eq do |str1 = '', str2 = '', t = '', f = ''|

Equal. Tests if two strings are equal and returns the string t or f depending on the result of the test. Note that this is a string test for equality, so will not work for numerics. To compare numerically see the greater than command.

on :gr do |num1 = '', num2 = '', t = '', f = ''|

Greater Than. Compares the given Decimal values and returns the string t or f depending on the result of the test. To test two Decimal values for equality, test if neither is greater than the other.


I/O Commands

on :ps do |str = ''|

Print String. Prints to the console the first argument.

on :rc

Read Character. Reads a single character from the keyboard. This will read control characters as well as printable characters.

on :rs

Read String. Reads characters until the meta character is typed. Primitive editing characters are available:

/

Erases the previous character

@

Erases the entire input string

The editing characters don't change the appearance of input, they just change what the processor eventually sees. So for example, the following:

#(DD@#(PS,Hellp\o World!)'

will cause TRAC to print Hello World!

on :cm do |str|

Change Meta. Changes the meta character to the first character of the given string.


Block Commands

on :dd do |*names|

Delete Definitions. Deletes Form definitions that are bound to the given names. Names that are not bound will be ignored.

on :da

Delete all definitions. A synonym for +#(DD,#(LN,(,)))+.

on :ln do |delimiter = ''|

List Names. Lists names defined in the current binding using the given delimiter. The delimiter defaults to the empty string, which means the names will all run together.

on :sb do |name, *fnames|

Store Block. Creates a new block with the given name and stores the given forms in it. This will create a file in the savedir with the name given and an extension of .trl. The file itself will contain the TRAC commands necessary to recreate the forms given and position their form pointers to the correct place.

on :fb do |name = ''|

Fetch Block. Fetches the block with the given name and adds its forms to this environment. This will read the file given by the form value and execute each line of it as series of TRAC commands. The contents of the block Form given by the name does not have to use the same directory as the savedir, so you can load files from other directories if you want. However, the Executor that is executing the TRAC commands in the file is using the savedir option, so if the file in question has a #(SB) command, it will use the savedir in the Executor.

on :eb do |name = ''|

Erase Block. Deletes block and its corresponding file.


Math Commands

on :bc do |str = ''|

Bit Complement. Maps the mnemonic :bc to Octal.~.

# File lib/trac_lang/dispatch.rb, line 108
def self.on(sym)
  table[sym] = Proc.new
end

Public Instance Methods

dispatch(exp) click to toggle source

Dispatches command to TRAC procedure. If command received is a TRAC command, it's looked up in the table and executed. If not, the #(CL) command is called, and the result is forced to the active string.

# File lib/trac_lang/dispatch.rb, line 138
def dispatch(exp)
  if Dispatch.table.has_key?(exp.command)
    self.instance_exec(*exp.trac_args, &Dispatch.table[exp.command])
  else
    self.instance_exec(*exp.args, &Dispatch.table[:cl]).merge({force: true})
  end
end
return_empty() click to toggle source

Returns empty string. All returns are wrapped in a hash containing the return value and the force flag.

# File lib/trac_lang/dispatch.rb, line 114
def return_empty
  {value: '', force: false}
end
return_force(val) click to toggle source

Returns value and forces it to the active string.

# File lib/trac_lang/dispatch.rb, line 125
def return_force(val)
  {value: val, force: true}
end
return_value(val) click to toggle source

Returns value. All returns are wrapped in a hash containing the return value and the force flag.

# File lib/trac_lang/dispatch.rb, line 120
def return_value(val)
  {value: val, force: false}
end