Skip to content

Commit d603358

Browse files
committed
Rewrite statically mentioned symbols to point to pre-created objects.
1 parent 01c4c3c commit d603358

File tree

4 files changed

+40
-10
lines changed

4 files changed

+40
-10
lines changed

compile_pragma.rb

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,18 @@
55
#
66

77
class Compiler
8-
#
9-
# FIXME: We could go one better with this, and generate the
10-
# objects "raw". Will revisit that once I see if it is worth it.
11-
#
12-
def output_integer_list(scope)
13-
@integers.each do |i|
14-
compile_assign(scope, int_name(i), [:call, :__int, i])
8+
9+
def output_symbol_list(scope)
10+
@symbols.each do |s|
11+
compile_assign(scope, symbol_name(s), [:call, :__get_symbol, s])
1512
end
1613
Value.new([:global, :nil])
1714
end
1815

1916
def compile___compiler_internal scope, type, *args
2017
case type
21-
when :integer_list
22-
return output_integer_list(scope)
18+
when :symbol_list
19+
return output_symbol_list(scope)
2320
end
2421

2522
error("Unknown pragma: #{type}")

compiler.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class Compiler
4646
:lt, :le, :gt, :ge,:saveregs, :and, :or,
4747
:preturn, :proc, :stackframe, :deref, :include,
4848
:protected, :array, :splat, :mod, :or_assign, :break, :next,
49-
:__compiler_internal # See `compile_pragma.rb`
49+
:__compiler_internal, # See `compile_pragma.rb`
5050
]
5151

5252
Keywords = @@keywords

lib/core/symbol.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,5 @@ def self.__get_symbol(name)
109109
end
110110

111111
%s(defun __get_symbol (name) (callm Symbol __get_symbol ((__get_string name))))
112+
113+
%s(__compiler_internal symbol_list)

transform.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ def rewrite_strconst(exp)
106106
end
107107

108108

109+
def symbol_name(v)
110+
s = "__S_#{clean_method_name(v)}"
109111
def int_name(v)
110112
if v < 0
111113
# FIXME: @bug #{-v} causes error, because it tries to call Fixnum#- with single argument
@@ -143,7 +145,35 @@ def rewrite_integer_constant(exp)
143145
end
144146
end
145147

148+
# Rewrite a symbol constant outside %s() to
149+
# %s(sexp __[num]) and output a list later
150+
def rewrite_symbol_constant(exp)
151+
@symbols = Set[]
152+
exp.depth_first do |e|
153+
next :skip if e[0] == :sexp
154+
is_call = e[0] == :call || e[0] == :callm
155+
# FIXME: e seems to get aliased by v
156+
ex = e
157+
e.each_with_index do |v,i|
158+
name = v.to_s
159+
if v.is_a?(Symbol) && name[0] == ?:
160+
#STDERR.puts v.inspect
161+
if !@symbols.member?(v)
162+
@symbols << name[1..-1]
163+
end
164+
ex[i] = E[:sexp, symbol_name(name[1..-1])]
165+
166+
# FIXME: This is a horrible workaround to deal with a parser
167+
# inconsistency that leaves calls with a single argument with
168+
# the argument "bare" if it's not an array, which breaks with
169+
# this rewrite.
170+
ex[i] = E[ex[i]] if is_call && i > 1
171+
end
172+
end
173+
end
174+
end
146175

176+
147177
# Rewrite operators that should be treated as method calls
148178
# so that e.g. (+ 1 2) is turned into (callm 1 + 2)
149179
#
@@ -619,6 +649,7 @@ def preprocess exp
619649
rewrite_range(exp)
620650
rewrite_strconst(exp)
621651
rewrite_integer_constant(exp)
652+
rewrite_symbol_constant(exp)
622653
rewrite_operators(exp)
623654
rewrite_yield(exp)
624655
rewrite_let_env(exp)

0 commit comments

Comments
 (0)