1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/sample/rbc.rb
matz 210367ec88 This commit was generated by cvs2svn to compensate for changes in r372,
which included commits to RCS files with non-trunk default branches.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1999-01-20 04:59:39 +00:00

1015 lines
21 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/local/bin/ruby
#
# rbc.rb -
# $Release Version: 0.8 $
# $Revision: 1.8 $
# $Date: 1998/03/11 05:43:00 $
# by Keiju ISHITSUKA(Nippon Rational Inc.)
#
# --
# Usage:
#
# rbc.rb [options] file_name opts
# options:
# -d debug mode (not recommended)
# -f does not read ~/.irbrc
# -m bc mode (rational/matrix calc)
# -r load-module same as `ruby -r'
# --inspect use inspect for result output
# (default for non-bc mode)
# --noinspect does not use inspect for result output
# --noreadline does not use readline library
# (default: try to use readline)
#
# additional private method (as function):
# exit, quit terminate the interpreter
# inspect_mode(sw = nil) toggle inspect mode
# trace_load(sw = nil) change trace mode for file loading using
# load/require. (default: trace-mode on)
#
require "e2mmap.rb"
$stdout.sync = TRUE
module BC_APPLICATION__
RCS_ID='-$Id: rbc.rb,v 1.8 1998/03/11 05:43:00 keiju Exp keiju $-'
extend Exception2MessageMapper
def_exception :UnrecognizedSwitch, "Unrecognized switch: %s"
CONFIG = {}
CONFIG[0] = $0
CONFIG[:USE_READLINE] = TRUE
CONFIG[:LOAD_MODULES] = []
CONFIG[:INSPECT] = nil
CONFIG[:TRACE_LOAD] = FALSE
CONFIG[:RC] = TRUE
CONFIG[:DEBUG] = FALSE
while opt = ARGV.shift
case opt
when "-d"
CONFIG[:DEBUG] = TRUE
when "-m"
CONFIG[:INSPECT] = FALSE if CONFIG[:INSPECT].nil?
require "mathn.rb"
include Math
when "-r"
opt = ARGV.shift
CONFIG[:LOAD_MODULES].push opt if opt
when "-f"
opt = ARGV.shift
CONFIG[:RC] = FALSE
when "--inspect"
CONFIG[:INSPECT] = TRUE
when "--noinspect"
CONFIG[:INSPECT] = FALSE
when "--noreadline"
CONFIG[:USE_READLINE] = FALSE
when /^-/
# print UnrecognizedSwitch.inspect, "\n"
BC_APPLICATION__.fail UnrecognizedSwitch, opt
else
CONFIG[:USE_READLINE] = FALSE
$0 = opt
break
end
end
CONFIG[:INSPECT] = TRUE if CONFIG[:INSPECT].nil?
PROMPTi = "rbc%d> "
PROMPTs = "rbc%d%s "
PROMPTe = "rbc%d* "
class BC
def initialize
lex_init
end
def eval_input(io, cont, bind)
line = ''
@io = io
@ltype = nil
@quoted = nil
@indent = 0
@lex_state = EXPR_BEG
@io.prompt = format(PROMPTi, @indent)
loop do
@continue = FALSE
l = @io.gets
unless l
break if line == ''
else
line = line + l
lex(l) if l != "\n"
print @quoted.inspect, "\n" if CONFIG[:DEBUG]
if @ltype
@io.prompt = format(PROMPTs, @indent, @ltype)
next
elsif @continue
@io.prompt = format(PROMPTe, @indent)
next
elsif @indent > 0
@io.prompt = format(PROMPTi, @indent)
next
end
end
if line != "\n"
begin
if CONFIG[:INSPECT]
print((cont._=eval(line, bind)).inspect, "\n")
else
print((cont._=eval(line, bind)), "\n")
end
rescue
# $! = 'exception raised' unless $!
# print "ERR: ", $!, "\n"
$! = RuntimeError.new("exception raised") unless $!
print $!.type, ": ", $!, "\n"
end
end
break if not l
line = ''
indent = 0
@io.prompt = format(PROMPTi, indent)
end
print "\n"
end
EXPR_BEG = :EXPR_BEG
EXPR_MID = :EXPR_MID
EXPR_END = :EXPR_END
EXPR_ARG = :EXPR_ARG
EXPR_FNAME = :EXPR_FNAME
CLAUSE_STATE_TRANS = {
"alias" => EXPR_FNAME,
"and" => EXPR_BEG,
"begin" => EXPR_BEG,
"case" => EXPR_BEG,
"class" => EXPR_BEG,
"def" => EXPR_FNAME,
"defined?" => EXPR_END,
"do" => EXPR_BEG,
"else" => EXPR_BEG,
"elsif" => EXPR_BEG,
"end" => EXPR_END,
"ensure" => EXPR_BEG,
"for" => EXPR_BEG,
"if" => EXPR_BEG,
"in" => EXPR_BEG,
"module" => EXPR_BEG,
"nil" => EXPR_END,
"not" => EXPR_BEG,
"or" => EXPR_BEG,
"rescue" => EXPR_MID,
"return" => EXPR_MID,
"self" => EXPR_END,
"super" => EXPR_END,
"then" => EXPR_BEG,
"undef" => EXPR_FNAME,
"unless" => EXPR_BEG,
"until" => EXPR_BEG,
"when" => EXPR_BEG,
"while" => EXPR_BEG,
"yield" => EXPR_END
}
ENINDENT_CLAUSE = [
"case", "class", "def", "do", "for", "if",
"module", "unless", "until", "while", "begin" #, "when"
]
DEINDENT_CLAUSE = ["end" #, "when"
]
PARCENT_LTYPE = {
"q" => "\'",
"Q" => "\"",
"x" => "\`",
"r" => "\/"
}
PARCENT_PAREN = {
"{" => "}",
"[" => "]",
"<" => ">",
"(" => ")"
}
def lex_init()
@OP = Trie.new
@OP.def_rules("\0", "\004", "\032"){}
@OP.def_rules(" ", "\t", "\f", "\r", "\13") do
@space_seen = TRUE
next
end
@OP.def_rule("#") do
|op, rests|
@ltype = "#"
identify_comment(rests)
end
@OP.def_rule("\n") do
print "\\n\n" if CONFIG[:DEBUG]
if @lex_state == EXPR_BEG || @lex_state == EXPR_FNAME
@continue = TRUE
else
@lex_state = EXPR_BEG
end
end
@OP.def_rules("*", "*=", "**=", "**") {@lex_state = EXPR_BEG}
@OP.def_rules("!", "!=", "!~") {@lex_state = EXPR_BEG}
@OP.def_rules("=", "==", "===", "=~", "<=>") {@lex_state = EXPR_BEG}
@OP.def_rules("<", "<=", "<<") {@lex_state = EXPR_BEG}
@OP.def_rules(">", ">=", ">>") {@lex_state = EXPR_BEG}
@OP.def_rules("'", '"') do
|op, rests|
@ltype = op
@quoted = op
identify_string(rests)
end
@OP.def_rules("`") do
|op, rests|
if @lex_state != EXPR_FNAME
@ltype = op
@quoted = op
identify_string(rests)
end
end
@OP.def_rules('?') do
|op, rests|
@lex_state = EXPR_END
identify_question(rests)
end
@OP.def_rules("&", "&&", "&=", "|", "||", "|=") do
@lex_state = EXPR_BEG
end
@OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) {}
@OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) {}
@OP.def_rules("+=", "-=") {@lex_state = EXPR_BEG}
@OP.def_rules("+", "-") do
|op, rests|
if @lex_state == EXPR_ARG
if @space_seen and rests[0] =~ /[0-9]/
identify_number(rests)
else
@lex_state = EXPR_BEG
end
elsif @lex_state != EXPR_END and rests[0] =~ /[0-9]/
identify_number(rests)
else
@lex_state = EXPR_BEG
end
end
@OP.def_rule(".") do
|op, rests|
@lex_state = EXPR_BEG
if rests[0] =~ /[0-9]/
rests.unshift op
identify_number(rests)
else
# obj.if <20>ʤɤ<CAA4><C9A4>б<EFBFBD>
identify_identifier(rests, TRUE)
@lex_state = EXPR_ARG
end
end
@OP.def_rules("..", "...") {@lex_state = EXPR_BEG}
lex_int2
end
def lex_int2
@OP.def_rules("]", "}", ")") do
@lex_state = EXPR_END
@indent -= 1
end
@OP.def_rule(":") {|op,rests|
identify_identifier(rests, TRUE)
}
@OP.def_rule("::") {|op,rests|
identify_identifier(rests, TRUE);
}
@OP.def_rule("/") do
|op, rests|
if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
@ltype = op
@quoted = op
identify_string(rests)
elsif rests[0] == '='
rests.shift
@lex_state = EXPR_BEG
elsif @lex_state == EXPR_ARG and @space_seen and rests[0] =~ /\s/
@ltype = op
@quoted = op
identify_string(rests)
else
@lex_state = EXPR_BEG
end
end
@OP.def_rules("^", "^=") {@lex_state = EXPR_BEG}
@OP.def_rules(",", ";") {@lex_state = EXPR_BEG}
@OP.def_rule("~") {@lex_state = EXPR_BEG}
@OP.def_rule("~@", proc{@lex_state = EXPR_FNAME}) {}
@OP.def_rule("(") do
@lex_state = EXPR_BEG
@indent += 1
end
@OP.def_rule("[]", proc{@lex_state == EXPR_FNAME}) {}
@OP.def_rule("[]=", proc{@lex_state == EXPR_FNAME}) {}
@OP.def_rule("[") do
@indent += 1
if @lex_state != EXPR_FNAME
@lex_state = EXPR_BEG
end
end
@OP.def_rule("{") do
@lex_state = EXPR_BEG
@indent += 1
end
@OP.def_rule('\\') {|op, rests| identify_escape(rests)} #')
@OP.def_rule('%') do
|op, rests|
if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
identify_quotation(rests)
elsif rests[0] == '='
rests.shift
elsif @lex_state == EXPR_ARG and @space_seen and rests[0] =~ /\s/
identify_quotation(rests)
else
@lex_state = EXPR_BEG
end
end
@OP.def_rule('$') do
|op, rests|
identify_gvar(rests)
end
@OP.def_rule('@') do
|op, rests|
if rests[0] =~ /[\w_]/
rests.unshift op
identify_identifier(rests)
end
end
@OP.def_rule("def", proc{|op, chrs| /\s/ =~ chrs[0]}) do
|op, rests|
@indent += 1
@lex_state = EXPR_END
until rests[0] == "\n" or rests[0] == ";"
rests.shift
end
end
@OP.def_rule("") do
|op, rests|
printf "MATCH: start %s: %s\n", op, rests.inspect if CONFIG[:DEBUG]
if rests[0] =~ /[0-9]/
identify_number(rests)
elsif rests[0] =~ /[\w_]/
identify_identifier(rests)
end
printf "MATCH: end %s: %s\n", op, rests.inspect if CONFIG[:DEBUG]
end
p @OP if CONFIG[:DEBUG]
end
def lex(l)
chrs = l.split(//)
tokens = []
case @ltype
when "'", '"', '`', '/'
identify_string(chrs)
return if chrs.empty?
when "#"
identify_comment(chrs)
return
when "="
if l =~ /^=end/
$ltype = nil
return
end
else
if l =~ /^=begin/
$ltype = "="
return
end
end
until chrs.empty?
@space_seen = FALSE
printf "perse: %s\n", chrs.join("") if CONFIG[:DEBUG]
@OP.match(chrs)
printf "lex_state: %s continue: %s\n", @lex_state.id2name, @continue if CONFIG[:DEBUG]
end
end
def identify_gvar(chrs)
@lex_state = EXPR_END
ch = chrs.shift
case ch
when /[_~*$?!@/\\;,.=:<>"]/ #"
return
when "-"
ch = chrs.shift
return
when "&", "`", "'", "+"
return
when /[1-9]/
chrs.unshift ch
v = "$"
while (ch = chrs.shift) =~ /[0-9]/
end
chrs.unshift ch
return
when /\w/
chrs.unshift ch
chrs.unshift "$"
identify_identifier(chrs)
return
else
chrs.unshift ch
return
end
end
def identify_identifier(chrs, escaped = FALSE)
token = ""
token.concat chrs.shift if chrs[0] =~ /[$@]/ or escaped
while (ch = chrs.shift) =~ /\w|_/
print ":", ch, ":" if CONFIG[:DEBUG]
token.concat ch
end
chrs.unshift ch
if ch == "!" or ch == "?"
chrs.shift
token.concat ch
end
# fix token
if token =~ /^[$@]/ or escaped
@lex_state = EXPR_END
return
end
print token, "\n" if CONFIG[:DEBUG]
if state = CLAUSE_STATE_TRANS[token]
if @lex_state != EXPR_BEG and token =~ /^(if|unless|while|until)/
# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else
if ENINDENT_CLAUSE.include?(token)
@indent += 1
elsif DEINDENT_CLAUSE.include?(token)
@indent -= 1
end
end
@lex_state = state
return
end
if @lex_state == EXPR_FNAME
@lex_state = EXPR_END
if chrs[0] == '='
chrs.shift
end
elsif @lex_state == EXPR_BEG
@lex_state = EXPR_ARG
else
@lex_state = EXPR_END
end
end
def identify_quotation(chrs)
ch = chrs.shift
if lt = PARCENT_LTYPE[ch]
ch = chrs.shift
else
lt = "\""
end
if ch !~ /\W/
chrs.unshift ch
next
end
@ltype = lt
unless @quoted = PARCENT_PAREN[ch]
@quoted = ch
end
identify_string(chrs)
end
def identify_number(chrs)
@lex_state = EXPR_END
ch = chrs.shift
case ch
when /0/
if (ch = chrs[0]) == "x"
chrs.shift
match = /[0-9a-f_]/
else
match = /[0-7_]/
end
while ch = chrs.shift
if ch !~ match
chrs.unshift ch
break
end
end
return
end
while ch = chrs.shift
case ch
when /[0-9]/
when "e", "E"
# type = FLOAT
unless (ch = chrs.shift) == "+" or ch == "-"
chrs.unshift ch
end
when "."
# type = FLOAT
when "_"
else
chrs.unshift ch
return
end
end
end
def identify_question(chrs)
@lex_state = EXPR_END
if chrs.shift == "\\" #"
identify_escape(chrs)
end
end
def identify_string(chrs)
while ch = chrs.shift
if @quoted == ch
if @ltype == "/"
if chrs[0] =~ /i|o|n|e|s/
chrs.shift
end
end
@ltype = nil
@quoted = nil
@lex_state = EXPR_END
break
elsif ch == '\\' #'
identify_escape(chrs)
end
end
end
def identify_comment(chrs)
while ch = chrs.shift
if ch == "\\" #"
identify_escape(chrs)
end
if ch == "\n"
@ltype = nil
chrs.unshift ch
break
end
end
end
def identify_escape(chrs)
ch = chrs.shift
case ch
when "\n", "\r", "\f"
@continue = TRUE
when "\\", "n", "t", "r", "f", "v", "a", "e", "b" #"
when /[0-7]/
chrs.unshift ch
3.times do
ch = chrs.shift
case ch
when /[0-7]/
when nil
break
else
chrs.unshift ch
break
end
end
when "x"
2.times do
ch = chrs.shift
case ch
when /[0-9a-fA-F]/
when nil
break
else
chrs.unshift ch
break
end
end
when "M"
if (ch = chrs.shift) != '-'
chrs.unshift ch
elsif (ch = chrs.shift) == "\\" #"
identify_escape(chrs)
end
return
when "C", "c", "^"
if ch == "C" and (ch = chrs.shift) != "-"
chrs.unshift ch
elsif (ch = chrs.shift) == "\\" #"
identify_escape(chrs)
end
return
end
end
end
class Trie
extend Exception2MessageMapper
def_exception :ErrNodeNothing, "node nothing"
def_exception :ErrNodeAlreadyExists, "node already exists"
class Node
# postproc<6F><63><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݥΡ<DDA5><CEA1><EFBFBD>, nil<69><6C><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>ݥΡ<DDA5><CEA1><EFBFBD>
def initialize(preproc = nil, postproc = nil)
@Tree = {}
@preproc = preproc
@postproc = postproc
end
attr :preproc, TRUE
attr :postproc, TRUE
def search(chrs, opt = nil)
return self if chrs.empty?
ch = chrs.shift
if node = @Tree[ch]
node.search(chrs, opt)
else
if opt
chrs.unshift ch
self.create_subnode(chrs)
else
Trie.fail ErrNodeNothing
end
end
end
def create_subnode(chrs, preproc = nil, postproc = nil)
if chrs.empty?
if @postproc
p node
Trie.fail ErrNodeAlreadyExists
else
print "Warn: change abstruct node to real node\n" if CONFIG[:DEBUG]
@preproc = preproc
@postproc = postproc
end
return self
end
ch = chrs.shift
if node = @Tree[ch]
if chrs.empty?
if node.postproc
p node
Trie.fail ErrNodeAlreadyExists
else
print "Warn: change abstruct node to real node\n" if CONFIG[:DEBUG]
node.preproc = preproc
node.postproc = postproc
end
else
node.create_subnode(chrs, preproc, postproc)
end
else
if chrs.empty?
node = Node.new(preproc, postproc)
else
node = Node.new
node.create_subnode(chrs, preproc, postproc)
end
@Tree[ch] = node
end
node
end
def match(chrs, op = "")
print "match>: ", chrs, "op:", op, "\n" if CONFIG[:DEBUG]
if chrs.empty?
if @preproc.nil? || @preproc.call(op, chrs)
printf "op1: %s\n", op if CONFIG[:DEBUG]
@postproc.call(op, chrs)
""
else
nil
end
else
ch = chrs.shift
if node = @Tree[ch]
if ret = node.match(chrs, op+ch)
return ch+ret
else
chrs.unshift ch
if @postproc and @preproc.nil? || @preproc.call(op, chrs)
printf "op2: %s\n", op.inspect if CONFIG[:DEBUG]
@postproc.call(op, chrs)
return ""
else
return nil
end
end
else
chrs.unshift ch
if @postproc and @preproc.nil? || @preproc.call(op, chrs)
printf "op3: %s\n", op if CONFIG[:DEBUG]
@postproc.call(op, chrs)
return ""
else
return nil
end
end
end
end
end
def initialize
@head = Node.new("")
end
def def_rule(token, preproc = nil, postproc = nil)
# print node.inspect, "\n" if CONFIG[:DEBUG]
postproc = proc if iterator?
node = create(token, preproc, postproc)
end
def def_rules(*tokens)
if iterator?
p = proc
end
for token in tokens
def_rule(token, nil, p)
end
end
def preporc(token, proc)
node = search(token)
node.preproc=proc
end
def postproc(token)
node = search(token, proc)
node.postproc=proc
end
def search(token)
@head.search(token.split(//))
end
def create(token, preproc = nil, postproc = nil)
@head.create_subnode(token.split(//), preproc, postproc)
end
def match(token)
token = token.split(//) if token.kind_of?(String)
ret = @head.match(token)
printf "match end: %s:%s", ret, token.inspect if CONFIG[:DEBUG]
ret
end
def inspect
format("<Trie: @head = %s>", @head.inspect)
end
end
if /^-tt(.*)$/ =~ ARGV[0]
# Tracer.on
case $1
when "1"
tr = Trie.new
print "0: ", tr.inspect, "\n"
tr.def_rule("=") {print "=\n"}
print "1: ", tr.inspect, "\n"
tr.def_rule("==") {print "==\n"}
print "2: ", tr.inspect, "\n"
print "case 1:\n"
print tr.match("="), "\n"
print "case 2:\n"
print tr.match("=="), "\n"
print "case 3:\n"
print tr.match("=>"), "\n"
when "2"
tr = Trie.new
print "0: ", tr.inspect, "\n"
tr.def_rule("=") {print "=\n"}
print "1: ", tr.inspect, "\n"
tr.def_rule("==", proc{FALSE}) {print "==\n"}
print "2: ", tr.inspect, "\n"
print "case 1:\n"
print tr.match("="), "\n"
print "case 2:\n"
print tr.match("=="), "\n"
print "case 3:\n"
print tr.match("=>"), "\n"
end
exit
end
module CONTEXT
def _=(value)
CONFIG[:_] = value
eval "_=BC_APPLICATION__::CONFIG[:_]", CONFIG[:BIND]
end
# def _
# eval "_", CONFIG[:BIND]
# end
def quit
exit
end
def trace_load(opt = nil)
if !opt.nil?
CONFIG[:TRACE_LOAD] = opt
else
CONFIG[:TRACE_LOAD] = !CONFIG[:TRACE_LOAD]
end
print "Switch to load/require #{unless CONFIG[:TRACE_LOAD]; ' non';end} trace mode.\n"
if CONFIG[:TRACE_LOAD]
eval %{
class << self
alias load rbc_load
alias require rbc_require
end
}
else
eval %{
class << self
alias load rbc_load_org
alias require rbc_require_org
end
}
end
CONFIG[:TRACE_LOAD]
end
alias rbc_load_org load
def rbc_load(file_name)
return true if load_sub(file_name)
raise LoadError, "No such file to load -- #{file_name}"
end
alias rbc_require_org require
def rbc_require(file_name)
rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
return false if $".find{|f| f =~ rex}
case file_name
when /\.rb$/
if load_sub(file_name)
$".push file_name
return true
end
when /\.(so|o|sl)$/
rbc_require_org(file_name)
end
if load_sub(f = file_name + ".rb")
$".push f
return true
end
rbc_require_org(file_name)
end
def load_sub(fn)
if fn =~ /^#{Regexp.quote(File::Separator)}/
return false unless File.exist?(fn)
BC.new.eval_input FileInputMethod.new(fn), self, CONFIG[:BIND]
return true
end
for path in $:
if File.exist?(f = File.join(path, fn))
BC.new.eval_input FileInputMethod.new(f), self, CONFIG[:BIND]
return true
end
end
return false
end
def inspect_mode(opt = nil)
if opt
CONFIG[:INSPECT] = opt
else
CONFIG[:INSPECT] = !CONFIG[:INSPECT]
end
print "Switch to#{unless CONFIG[:INSPECT]; ' non';end} inspect mode.\n"
CONFIG[:INSPECT]
end
def run(bind)
CONFIG[:BIND] = bind
if CONFIG[:RC]
rc = File.expand_path("~/.irbrc")
if File.exists?(rc)
begin
load rc
rescue
print "load error: #{rc}\n"
print $!.type, ": ", $!, "\n"
for err in $@[0, $@.size - 2]
print "\t", err, "\n"
end
end
end
end
if CONFIG[:TRACE_LOAD]
trace_load true
end
for m in CONFIG[:LOAD_MODULES]
begin
require m
rescue
print $@[0], ":", $!.type, ": ", $!, "\n"
end
end
if !$0.equal?(CONFIG[0])
io = FileInputMethod.new($0)
elsif defined? Readline
io = ReadlineInputMethod.new
else
io = StdioInputMethod.new
end
BC.new.eval_input io, self, CONFIG[:BIND]
end
end
class InputMethod
attr :prompt, TRUE
def gets
end
public :gets
end
class StdioInputMethod < InputMethod
def gets
print @prompt
$stdin.gets
end
end
class FileInputMethod < InputMethod
def initialize(file)
@io = open(file)
end
def gets
l = @io.gets
print @prompt, l
l
end
end
if CONFIG[:USE_READLINE]
begin
require "readline"
print "use readline module\n"
class ReadlineInputMethod < InputMethod
include Readline
def gets
if l = readline(@prompt, TRUE)
l + "\n"
else
l
end
end
end
rescue
CONFIG[:USE_READLINE] = FALSE
end
end
end
extend BC_APPLICATION__::CONTEXT
run(binding)