Skip to content

Commit

Permalink
Implement interop with Ruby constants
Browse files Browse the repository at this point in the history
  • Loading branch information
Josep M. Bach committed Mar 5, 2014
1 parent fab156c commit 6edbc77
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 4 deletions.
9 changes: 9 additions & 0 deletions lib/lambra/bytecode_compiler.rb
Expand Up @@ -190,6 +190,8 @@ def visit_PrimitiveForm(car, cdr)
def visit_Symbol(o) def visit_Symbol(o)
if o.name.to_sym == :self if o.name.to_sym == :self
return visit_Self(o) return visit_Self(o)
elsif o.name =~ /^[A-Z]/
return visit_Constant(o)
end end


set_line(o) set_line(o)
Expand All @@ -207,6 +209,13 @@ def visit_Self(o)
g.send :pid, 0 g.send :pid, 0
end end


def visit_Constant(o)
g.push_cpath_top
o.name.to_s.split('.').each do |part|
g.find_const(part.to_sym)
end
end

def visit_Number(o) def visit_Number(o)
set_line(o) set_line(o)
g.push_literal o.value g.push_literal o.value
Expand Down
2 changes: 1 addition & 1 deletion lib/lambra/parser/lambra.kpeg
Expand Up @@ -39,7 +39,7 @@ true = "true" ~true_value(current_line, current_column)
false = "false" ~false_value(current_line, current_column) false = "false" ~false_value(current_line, current_column)
nil = "nil" ~nil_value(current_line, current_column) nil = "nil" ~nil_value(current_line, current_column)


word = < /\.?[a-zA-Z0-9_\-\*\+\-\/]+/ > { text } word = < /[A-Z\.]?[a-zA-Z0-9_\.\-\*\+\-\/]+/ > { text }
symbol = word:w ~symbol(current_line, current_column, w.to_sym) symbol = word:w ~symbol(current_line, current_column, w.to_sym)
keyword = ":" word:w ~keyword(current_line, current_column, w.to_sym) keyword = ":" word:w ~keyword(current_line, current_column, w.to_sym)


Expand Down
6 changes: 3 additions & 3 deletions lib/lambra/parser/parser.rb
Expand Up @@ -862,13 +862,13 @@ def _nil
return _tmp return _tmp
end end


# word = < /\.?[a-zA-Z0-9_\-\*\+\-\/]+/ > { text } # word = < /[A-Z\.]?[a-zA-Z0-9_\.\-\*\+\-\/]+/ > { text }
def _word def _word


_save = self.pos _save = self.pos
while true # sequence while true # sequence
_text_start = self.pos _text_start = self.pos
_tmp = scan(/\A(?-mix:\.?[a-zA-Z0-9_\-\*\+\-\/]+)/) _tmp = scan(/\A(?-mix:[A-Z\.]?[a-zA-Z0-9_\.\-\*\+\-\/]+)/)
if _tmp if _tmp
text = get_text(_text_start) text = get_text(_text_start)
end end
Expand Down Expand Up @@ -1681,7 +1681,7 @@ def _root
Rules[:_true] = rule_info("true", "\"true\" {true_value(current_line, current_column)}") Rules[:_true] = rule_info("true", "\"true\" {true_value(current_line, current_column)}")
Rules[:_false] = rule_info("false", "\"false\" {false_value(current_line, current_column)}") Rules[:_false] = rule_info("false", "\"false\" {false_value(current_line, current_column)}")
Rules[:_nil] = rule_info("nil", "\"nil\" {nil_value(current_line, current_column)}") Rules[:_nil] = rule_info("nil", "\"nil\" {nil_value(current_line, current_column)}")
Rules[:_word] = rule_info("word", "< /\\.?[a-zA-Z0-9_\\-\\*\\+\\-\\/]+/ > { text }") Rules[:_word] = rule_info("word", "< /[A-Z\\.]?[a-zA-Z0-9_\\.\\-\\*\\+\\-\\/]+/ > { text }")
Rules[:_symbol] = rule_info("symbol", "word:w {symbol(current_line, current_column, w.to_sym)}") Rules[:_symbol] = rule_info("symbol", "word:w {symbol(current_line, current_column, w.to_sym)}")
Rules[:_keyword] = rule_info("keyword", "\":\" word:w {keyword(current_line, current_column, w.to_sym)}") Rules[:_keyword] = rule_info("keyword", "\":\" word:w {keyword(current_line, current_column, w.to_sym)}")
Rules[:_string] = rule_info("string", "\"\\\"\" < /[^\\\\\"]*/ > \"\\\"\" {string_value(current_line, current_column, text)}") Rules[:_string] = rule_info("string", "\"\\\"\" < /[^\\\\\"]*/ > \"\\\"\" {string_value(current_line, current_column, text)}")
Expand Down
8 changes: 8 additions & 0 deletions spec/compiler_spec.rb
Expand Up @@ -93,5 +93,13 @@
it 'works with methods' do it 'works with methods' do
"(.succ 3)".should eval_to 4 "(.succ 3)".should eval_to 4
end end

it 'works with simple constants' do
"Set".should eval_to Set
end

it 'works with qualified constants' do
"Lambra.Parser".should eval_to Lambra::Parser
end
end end
end end

0 comments on commit 6edbc77

Please sign in to comment.