Module: Red

Defined in:
lib/red.rb,
lib/red/errors.rb,
lib/red/plugin.rb,
lib/red/nodes/call_nodes.rb,
lib/red/nodes/data_nodes.rb,
lib/red/nodes/control_nodes.rb,
lib/red/nodes/illegal_nodes.rb,
lib/red/nodes/literal_nodes.rb,
lib/red/nodes/variable_nodes.rb,
lib/red/nodes/assignment_nodes.rb,
lib/red/nodes/definition_nodes.rb

Overview

:nodoc:

Defined Under Namespace

Modules: RailsBase Classes: AssignmentNode, BuildError, CallNode, ControlNode, DataNode, DefinitionNode, IllegalNode, LiteralNode, VariableNode

Constant Summary collapse

VERSION =
'4.1.7'
ARRAY_NODES =
{
  :and          => LogicNode::Conjunction::And,
  :alias        => DefinitionNode::Alias,
  #:argscat      => IllegalNode::MultipleAssignmentNode,
  #:argspush     => IllegalNode::MultipleAssignmentNode,
  :array        => LiteralNode::Array,
  :attrasgn     => AssignmentNode::Attribute,
  :begin        => ControlNode::Begin,
  :block        => LiteralNode::Multiline,
  :block_arg    => CallNode::Block::Ampersand,
  :block_pass   => CallNode::Ampersand,
  :break        => ControlNode::Keyword::Break,
  :call         => CallNode::Method::ExplicitReceiver,
  :case         => LogicNode::Case,
  :class        => DefinitionNode::Class,
  :cdecl        => AssignmentNode::Constant,
  :colon2       => LiteralNode::Namespace,
  :colon3       => LiteralNode::Namespace::TopLevel,
  :const        => VariableNode::Constant,
  :cvar         => VariableNode::ClassVariable,
  :cvasgn       => AssignmentNode::ClassVariable,
  :cvdecl       => AssignmentNode::ClassVariable,
  :dasgn        => AssignmentNode::LocalVariable,
  :dasgn_curr   => AssignmentNode::LocalVariable,
  :defined      => CallNode::Defined,
  :defn         => DefinitionNode::Method::Instance,
  :defs         => DefinitionNode::Method::Singleton,
  :dot2         => LiteralNode::Range,
  :dot3         => LiteralNode::Range::Exclusive,
  :dregx        => LiteralNode::Regexp,
  :dregx_once   => IllegalNode::RegexEvaluationNode,
  :dstr         => LiteralNode::String,
  :dsym         => LiteralNode::Symbol,
  :dvar         => VariableNode::OtherVariable,
  :dxstr        => LiteralNode::Uninterpreted,
  :ensure       => ControlNode::Ensure,
  :evstr        => LiteralNode::String,
  :false        => LogicNode::Boolean::False,
  :fcall        => CallNode::Method::ImplicitReceiver,
  :flip2        => IllegalNode::FlipflopNode,
  :flip3        => IllegalNode::FlipflopNode,
  :for          => ControlNode::For,
  :gasgn        => AssignmentNode::GlobalVariable,
  :gvar         => VariableNode::OtherVariable,
  :hash         => LiteralNode::Hash,
  :iasgn        => AssignmentNode::InstanceVariable,
  :if           => LogicNode::If,
  :iter         => CallNode::Block,
  :ivar         => VariableNode::InstanceVariable,
  :lasgn        => AssignmentNode::LocalVariable,
  :lvar         => VariableNode::OtherVariable,
  :lit          => LiteralNode::Other,
  :match        => IllegalNode::MatchNode,
  :match2       => CallNode::Match,
  :match3       => CallNode::Match::Reverse,
  :masgn        => AssignmentNode::Multiple,
  :module       => DefinitionNode::Module,
  :next         => ControlNode::Keyword::Next,
  :nil          => VariableNode::Keyword::Nil,
  :not          => LogicNode::Not,
  :op_asgn1     => AssignmentNode::Operator::Bracket,
  :op_asgn2     => AssignmentNode::Operator::Dot,
  :op_asgn_and  => AssignmentNode::Operator::And,
  :op_asgn_or   => AssignmentNode::Operator::Or,
  :or           => LogicNode::Conjunction::Or,
  :postexe      => IllegalNode::PostexeNode,
  :redo         => ControlNode::Keyword::Redo,
  :regex        => LiteralNode::Regexp,
  :resbody      => ControlNode::RescueBody,
  :rescue       => ControlNode::Rescue,
  :retry        => IllegalNode::RetryNode,
  :return       => ControlNode::Return,
  :sclass       => DefinitionNode::SingletonClass,
  :scope        => DefinitionNode::Scope,
  :self         => VariableNode::Keyword::Self,
  :splat        => LiteralNode::Splat,
  :super        => CallNode::Super,
  :svalue       => LiteralNode::Other,
  :str          => LiteralNode::String,
  :sym          => LiteralNode::Symbol,
  :to_ary       => LiteralNode::Array,
  :true         => LogicNode::Boolean::True,
  :undef        => DefinitionNode::Undef,
  :until        => ControlNode::Loop::Until,
  :vcall        => CallNode::Method::ImplicitReceiver,
  :when         => LogicNode::Case::When,
  :while        => ControlNode::Loop::While,
  :xstr         => LiteralNode::Uninterpreted,
  :yield        => CallNode::Yield,
  :zarray       => LiteralNode::Array,
  :zsuper       => CallNode::Super::Delegate
}
DATA_NODES =
{
  Bignum        => DataNode::Numeric,
  Fixnum        => DataNode::Numeric,
  Float         => DataNode::Numeric,
  Range         => DataNode::Range,
  Regexp        => DataNode::Regexp,
  Symbol        => DataNode::Symbol,
  String        => DataNode::String,
  NilClass      => DataNode::Nil
}
METHOD_ESCAPE =
{
  :==           => :_eql2,
  :===          => :_eql3,
  :=~           => :_etld,
  :[]           => :_brac,
  :[]=          => :_breq,
  :<=           => :_lteq,
  :>=           => :_gteq,
  :<<           => :_ltlt,
  :>>           => :_gtgt,
  :<            => :_lthn,
  :>            => :_gthn,
  :'<=>'        => :_ltgt,
  :|            => :_pipe,
  :&            => :_ampe,
  :+            => :_plus,
  :+@           => :_posi,
  :-            => :_subt,
  :-@           => :_nega,
  :*            => :_star,
  :**           => :_str2,
  :/            => :_slsh,
  :%            => :_perc,
  :'^'          => :_care,
  :~            => :_tild
}
NATIVE_CONSTANTS =
%w{
  c$Object
  c$Module
  c$Class
  c$Comparable
  c$Enumerable
  c$Kernel
  c$Math
  c$Math.c$E
  c$Math.c$PI
  c$Array
  c$Exception
  c$StandardError
  c$ArgumentError
  c$IndexError
  c$RangeError
  c$RuntimeError
  c$TypeError
  c$FalseClass
  c$Hash
  c$MatchData
  c$NilClass
  c$Numeric
  c$Proc
  c$Range
  c$Regexp
  c$Regexp.c$IGNORECASE
  c$Regexp.c$EXTENDED
  c$Regexp.c$MULTILINE
  c$String
  c$Symbol
  c$Time
  c$TrueClass
}
INTERNAL_METHODS =
%w{
  []
  []=
  <=>
  ==
  ===
  allocate
  append_features
  backtrace
  block_given?
  call
  class
  each
  extend_object
  extended
  hash
  include
  included
  inherited
  initialize
  inspect
  is_a?
  join
  new
  raise
  sprintf
  superclass
  to_proc
  to_s
  to_str
}.map {|m| m.to_sym }
RAILS_LOADED =
true

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.debugObject



233
234
235
# File 'lib/red.rb', line 233

def self.debug
  false
end

.init(file = '') ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/red.rb', line 219

def self.init(file = '')
  @@red_filepath    = File.dirname(File.expand_path(file))
  @@namespace_stack = []
  @@red_constants   = NATIVE_CONSTANTS
  @@red_methods     = INTERNAL_METHODS
  @@red_function    = nil
  @@red_singleton   = nil
  @@red_block_arg   = nil
  @@red_import      = false
  @@red_boolean     = '`'
  @@red_required    = []
  return true
end

.railsObject



256
257
258
# File 'lib/red.rb', line 256

def self.rails
  require 'red/plugin'
end

.update?(basename) ⇒ Boolean

Returns:

  • (Boolean)


17
18
19
20
# File 'lib/red/plugin.rb', line 17

def self.update?(basename)
  return true unless File.exists?('public/javascripts/%s.js' % basename)
  return (File.mtime('public/javascripts/red/%s.red' % basename) rescue File.mtime('public/javascripts/red/%s.rb' % basename)) > File.mtime('public/javascripts/%s.js' % basename)
end

.update_javascriptsObject



2
3
4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/red/plugin.rb', line 2

def self.update_javascripts
  red_dir = 'public/javascripts/red/'
  (Dir.glob("%s/*.red" % red_dir) + Dir.glob("%s/*.rb" % red_dir)).each do |filepath|
    basename = File.basename(filepath).gsub(/\.(rb|red)/,'')
    if self.update?(basename)
      Red.init(filepath)
      js_output = File.read(filepath).translate_to_sexp_array.red!
      ruby_js   = compile_ruby_js_source
      pre  = Red.debug ? "try{" : ""
      post = Red.debug ? "}catch(e){if(e.__class__){m$raise(e);};$ee=e;var m=e.message.match(/([^\\$]+)\\.m\\$(\\w+)\\sis\\snot\\sa\\sfunction/);if(m){m$raise(c$NoMethodError,$q('undefined method \"'+m[2]+'\" for '+m[1]));};var c=e.message.match(/([\\s\\S]+)\\sis\\sundefined/);if(c){c=c[1].replace(/\\./g,'::').replace(/c\\$/g,'');m$raise(c$NameError,$q('uninitialized constant '+c));};}" : ""
      File.open("public/javascripts/%s.js" % basename, 'w') {|f| f.write(pre + ruby_js + js_output + post)}
    end
  end
end

Instance Method Details

#is_sexp?(*sexp_types) ⇒ Boolean

Returns:

  • (Boolean)


252
253
254
# File 'lib/red.rb', line 252

def is_sexp?(*sexp_types)
  self.is_a?(Array) && sexp_types.include?(self.first)
end

#javascript_safe_succ!(string) ⇒ Object



260
261
262
263
264
# File 'lib/red.rb', line 260

def javascript_safe_succ!(string)
  string.succ!
  string.succ! if %w(as break byte case catch char class const do else enum false final float for goto if in int is long on new null short super this throw true try use var void while with).include?(string)
  return string
end

#red!(options = {}, reset = false) ⇒ Object



237
238
239
240
241
242
243
244
245
# File 'lib/red.rb', line 237

def red!(options = {}, reset = false)
  case self
  when Array
    raise(BuildError::UnknownNode, "Don't know how to handle sexp type :#{self.first}") unless ARRAY_NODES[self.first]
    return ARRAY_NODES[self.first].new(*(self[1..-1] + [options]))
  else
    return DATA_NODES[self.class].new(self, options)
  end
end

#translate_to_sexp_arrayObject

Raises:



247
248
249
250
# File 'lib/red.rb', line 247

def translate_to_sexp_array
  raise TypeError, "Can only translate Strings" unless self.is_a?(String)
  ParseTree.translate(self)
end