Skip to content

Commit

Permalink
Add Opal::Sexp instead of using Arrays for sexps
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 15, 2013
1 parent c559840 commit be34397
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 8 deletions.
3 changes: 3 additions & 0 deletions corelib/runtime.js
Expand Up @@ -544,6 +544,9 @@
if (value._isArray) {
return value;
}
else if (value.$to_ary && !value.$to_ary.rb_stub) {
return value.$to_ary();
}

return [value];
};
Expand Down
41 changes: 41 additions & 0 deletions lib/opal/core_ext.rb
Expand Up @@ -3,3 +3,44 @@ class Array
attr_accessor :end_line
end

module Opal
class Sexp

attr_accessor :line
attr_accessor :end_line
attr_reader :array

def initialize(args)
@array = args
end

def method_missing(sym, *args, &block)
@array.send sym, *args, &block
end

def to_ary
@array
end

def dup
Sexp.new(@array.dup)
end

def ==(other)
if other.is_a? Sexp
@array == other.array
else
@array == other
end
end

alias eql? ==

def inspect
"s(#{@array.map { |e| e.inspect }.join ', '})"
end

alias to_s inspect
end
end

2 changes: 1 addition & 1 deletion lib/opal/lexer.rb
Expand Up @@ -21,7 +21,7 @@ def initialize
end

def s(*parts)
sexp = Array.new(parts)
sexp = Sexp.new(parts)
sexp.line = @line
sexp
end
Expand Down
14 changes: 7 additions & 7 deletions lib/opal/parser.rb
Expand Up @@ -115,7 +115,7 @@ def parser_indent
#
# @result [Array]
def s(*parts)
sexp = Array.new(parts)
sexp = Sexp.new(parts)
sexp.line = @line
sexp
end
Expand Down Expand Up @@ -714,17 +714,17 @@ def process_iter(sexp, level)
args = args.first == :lasgn ? s(:array, args) : args[1]

# opt args are last, if present, and are a [:block]
if args.last.is_a?(Array) and args.last[0] == :block
if args.last.is_a?(Sexp) and args.last[0] == :block
opt_args = args.pop
opt_args.shift
end

if args.last.is_a?(Array) and args.last[0] == :block_pass
if args.last.is_a?(Sexp) and args.last[0] == :block_pass
block_arg = args.pop
block_arg = block_arg[1][1].to_sym
end

if args.last.is_a?(Array) and args.last[0] == :splat
if args.last.is_a?(Sexp) and args.last[0] == :splat
splat = args.last[1][1]
args.pop
len = args.length
Expand Down Expand Up @@ -851,7 +851,7 @@ def process_call(sexp, level)

splat = arglist[1..-1].any? { |a| a.first == :splat }

if Array === arglist.last and arglist.last.first == :block_pass
if Sexp === arglist.last and arglist.last.first == :block_pass
block = process(arglist.pop)
elsif iter
block = process(iter)
Expand Down Expand Up @@ -1104,7 +1104,7 @@ def js_def(recvr, mid, args, stmts, line, end_line, sexp, level)
uses_splat = nil

# opt args if last arg is sexp
opt = args.pop if Array === args.last
opt = args.pop if Sexp === args.last

argc = args.length - 1

Expand Down Expand Up @@ -2255,7 +2255,7 @@ def process_resbody(exp, level)
end
err << f("true", exp) if err.empty?

if Array === args.last and [:lasgn, :iasgn].include? args.last.first
if Sexp === args.last and [:lasgn, :iasgn].include? args.last.first
val = args.last
val[2] = s(:js_tmp, "$err")
val = [process(val) , f(";", exp)]
Expand Down

0 comments on commit be34397

Please sign in to comment.