From 1590713576d95f22531b384b3f8f82ce37e8c573 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Thu, 17 Dec 2009 09:37:42 -0500 Subject: [PATCH] passing through values with line number information that look and act like Ruby natives --- lib/coffee-script.rb | 2 ++ lib/coffee_script/lexer.rb | 2 +- lib/coffee_script/nodes.rb | 33 --------------------------------- lib/coffee_script/scope.rb | 33 +++++++++++++++++++++++++++++++++ lib/coffee_script/value.rb | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 34 deletions(-) create mode 100644 lib/coffee_script/scope.rb create mode 100644 lib/coffee_script/value.rb diff --git a/lib/coffee-script.rb b/lib/coffee-script.rb index 09be81f7..cfcf7de9 100644 --- a/lib/coffee-script.rb +++ b/lib/coffee-script.rb @@ -1,4 +1,6 @@ $LOAD_PATH.unshift(File.dirname(__FILE__)) +require "coffee_script/value" +require "coffee_script/scope" require "coffee_script/lexer" require "coffee_script/parser" require "coffee_script/nodes" diff --git a/lib/coffee_script/lexer.rb b/lib/coffee_script/lexer.rb index 62de56b7..17b2d486 100644 --- a/lib/coffee_script/lexer.rb +++ b/lib/coffee_script/lexer.rb @@ -123,7 +123,7 @@ class Lexer end def token(tag, value) - @tokens << [tag, value] + @tokens << [tag, Value.new(value, @line)] end def last_value diff --git a/lib/coffee_script/nodes.rb b/lib/coffee_script/nodes.rb index 96c1da76..d21c5edd 100644 --- a/lib/coffee_script/nodes.rb +++ b/lib/coffee_script/nodes.rb @@ -1,36 +1,3 @@ -class Scope - - attr_reader :parent, :temp_variable - - def initialize(parent=nil) - @parent = parent - @variables = {} - @temp_variable = @parent ? @parent.temp_variable : 'a' - end - - # Look up a variable in lexical scope, or declare it if not found. - def find(name, remote=false) - found = check(name, remote) - return found if found || remote - @variables[name] = true - found - end - - # Just check for the pre-definition of a variable. - def check(name, remote=false) - return true if @variables[name] - @parent && @parent.find(name, true) - end - - # Find an available, short variable name. - def free_variable - @temp_variable.succ! while check(@temp_variable) - @variables[@temp_variable] = true - @temp_variable.dup - end - -end - class Node # Tabs are two spaces for pretty-printing. TAB = ' ' diff --git a/lib/coffee_script/scope.rb b/lib/coffee_script/scope.rb new file mode 100644 index 00000000..a09fb7c9 --- /dev/null +++ b/lib/coffee_script/scope.rb @@ -0,0 +1,33 @@ +# A class to handle lookups for lexically scoped variables. +class Scope + + attr_reader :parent, :temp_variable + + def initialize(parent=nil) + @parent = parent + @variables = {} + @temp_variable = @parent ? @parent.temp_variable : 'a' + end + + # Look up a variable in lexical scope, or declare it if not found. + def find(name, remote=false) + found = check(name, remote) + return found if found || remote + @variables[name] = true + found + end + + # Just check for the pre-definition of a variable. + def check(name, remote=false) + return true if @variables[name] + @parent && @parent.find(name, true) + end + + # Find an available, short variable name. + def free_variable + @temp_variable.succ! while check(@temp_variable) + @variables[@temp_variable] = true + @temp_variable.dup + end + +end \ No newline at end of file diff --git a/lib/coffee_script/value.rb b/lib/coffee_script/value.rb new file mode 100644 index 00000000..19b56ed6 --- /dev/null +++ b/lib/coffee_script/value.rb @@ -0,0 +1,34 @@ +# Instead of producing raw Ruby objects, the Lexer produces values of this +# class, tagged with line number information. +class Value + attr_reader :line + + def initialize(value, line) + @value, @line = value, line + end + + def to_str + @value.to_s + end + alias_method :to_s, :to_str + + def inspect + @value.inspect + end + + def ==(other) + @value == other + end + + def [](index) + @value[index] + end + + def eql?(other) + @value.eql?(other) + end + + def hash + @value.hash + end +end \ No newline at end of file