Skip to content

Commit 617e72e

Browse files
committedJul 30, 2013
Add some more documentation to parser.rb
1 parent dae18e2 commit 617e72e

File tree

2 files changed

+39
-18
lines changed

2 files changed

+39
-18
lines changed
 

Diff for: ‎lib/opal/parser.rb

+38-18
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@
66
module Opal
77
class Parser
88

9+
# A fragment holds a string of generated javascript that will be written
10+
# to the destination. It also keeps hold of the original sexp from which
11+
# it was generated. Using this sexp, when writing fragments in order, a
12+
# mapping can be created of the original location => target location,
13+
# aka, source-maps!
914
class Fragment
10-
15+
# String of javascript this fragment holds
1116
attr_reader :code
1217

1318
def initialize(code, sexp = nil)
1419
@code = code
1520
@sexp = sexp
1621
end
1722

23+
# In debug mode we may wish to include the original line as a comment
1824
def to_code
1925
if @sexp
2026
"/*:#{@sexp.line}*/#{@code}"
@@ -23,8 +29,9 @@ def to_code
2329
end
2430
end
2531

32+
# inspect the contents of this fragment, f("fooo")
2633
def inspect
27-
"fragment(#{@code.inspect})"
34+
"f(#{@code.inspect})"
2835
end
2936
end
3037

@@ -51,8 +58,13 @@ def inspect
5158
# Statements which should not have ';' added to them.
5259
STATEMENTS = [:xstr, :dxstr]
5360

61+
# Final generated javascript for this parser
5462
attr_reader :result
5563

64+
# Parse some ruby code to a string.
65+
#
66+
# Opal::Parser.new.parse("1 + 2")
67+
# # => "(function() {....})()"
5668
def parse(source, options = {})
5769
@sexp = Grammar.new.parse(source, options[:file])
5870
@line = 1
@@ -83,6 +95,7 @@ def parse(source, options = {})
8395
@result = source_map_comment + version_comment + file_comment + code
8496
end
8597

98+
# Always at top of generated file to show current opal version
8699
def version_comment
87100
"/* Generated by Opal #{Opal::VERSION} */\n"
88101
end
@@ -168,6 +181,13 @@ def mid_to_jsid(mid)
168181
end
169182
end
170183

184+
# Converts a ruby lvar/arg name to a js identifier. Not all ruby names
185+
# are valid in javascript. A $ suffix is added to non-valid names.
186+
def lvar_to_js(var)
187+
var = "#{var}$" if RESERVED.include? var.to_s
188+
var.to_sym
189+
end
190+
171191
# Used to generate a unique id name per file. These are used
172192
# mainly to name method bodies for methods that use blocks.
173193
#
@@ -747,10 +767,7 @@ def process_iter(sexp, level)
747767
# s(:args, parts...) => ["a", "b", "break$"]
748768
def js_block_args(sexp)
749769
sexp.map do |arg|
750-
a = arg[1].to_sym
751-
a = "#{a}$".to_sym if RESERVED.include? a.to_s
752-
@scope.add_arg a
753-
a
770+
@scope.add_arg lvar_to_js(arg[1])
754771
end
755772
end
756773

@@ -1025,25 +1042,20 @@ def process_class(sexp, level)
10251042
code, fragment("\n#@indent})", sexp), fragment("(", sexp), base, fragment(", ", sexp), sup, fragment(")", sexp)]
10261043
end
10271044

1028-
# s(:sclass, recv, body)
1045+
# Singleton class syntax. Runs body in context of singleton_class.
1046+
# s(:sclass, recv, body) => (function() { ... }).call(recv.$singleton_class())
10291047
def process_sclass(sexp, level)
1030-
recv = sexp[0]
1031-
body = sexp[1]
1032-
code = []
1048+
recv, body, code = sexp[0], sexp[1], []
10331049

10341050
in_scope(:sclass) do
10351051
@scope.add_temp "__scope = #{current_self}._scope"
10361052
@scope.add_temp "def = #{current_self}._proto"
10371053

1038-
body = process body, :stmt
1039-
code << @scope.to_vars << body
1054+
code << @scope.to_vars << process(body, :stmt)
10401055
end
10411056

1042-
result = []
1043-
result << fragment("(function(){", sexp) << code
1044-
result << fragment("}).call(", sexp)
1045-
result << process(recv, :expr) << fragment(".$singleton_class())", sexp)
1046-
result
1057+
[f("(function(){", sexp), code, f("}).call(", sexp),
1058+
process(recv), f(".$singleton_class())", sexp)]
10471059
end
10481060

10491061
# s(:module, cid, body)
@@ -1095,6 +1107,7 @@ def process_module(sexp, level)
10951107

10961108
# undef :foo
10971109
# => delete MyClass.prototype.$foo
1110+
# FIXME: we should be setting method to a stub method here
10981111
def process_undef(sexp, level)
10991112
fragment("delete #{ @scope.proto }#{ mid_to_jsid sexp[0][1].to_s }", sexp)
11001113
end
@@ -1276,6 +1289,7 @@ def process_self(sexp, level)
12761289
# Returns the current value for 'self'. This will be native
12771290
# 'this' for methods and blocks, and the class name for class
12781291
# and module bodies.
1292+
# s(:self) => self or this or class name
12791293
def current_self
12801294
if @scope.class_scope?
12811295
@scope.name
@@ -1286,19 +1300,25 @@ def current_self
12861300
end
12871301
end
12881302

1303+
# true literal
1304+
# s(:true) => true
12891305
def process_true(sexp, level)
12901306
fragment("true", sexp)
12911307
end
12921308

1309+
# false literal
1310+
# s(:false) => false
12931311
def process_false(sexp, level)
12941312
fragment("false", sexp)
12951313
end
12961314

1315+
# nil literal
1316+
# s(:nil) => nil
12971317
def process_nil(sexp, level)
12981318
fragment("nil", sexp)
12991319
end
13001320

1301-
# s(:array [, sexp [, sexp]])
1321+
# s(:array [, sexp [, sexp]]) => [...]
13021322
def process_array(sexp, level)
13031323
return [fragment("[]", sexp)] if sexp.empty?
13041324

Diff for: ‎lib/opal/target_scope.rb

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ def add_proto_ivar(ivar)
168168

169169
def add_arg(arg)
170170
@args << arg unless @args.include? arg
171+
arg
171172
end
172173

173174
def add_local(local)

0 commit comments

Comments
 (0)
Please sign in to comment.