mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
passing through values with line number information that look and act like Ruby natives
This commit is contained in:
parent
146b5694c2
commit
1590713576
5 changed files with 70 additions and 34 deletions
|
@ -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"
|
||||
|
|
|
@ -123,7 +123,7 @@ class Lexer
|
|||
end
|
||||
|
||||
def token(tag, value)
|
||||
@tokens << [tag, value]
|
||||
@tokens << [tag, Value.new(value, @line)]
|
||||
end
|
||||
|
||||
def last_value
|
||||
|
|
|
@ -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 = ' '
|
||||
|
|
33
lib/coffee_script/scope.rb
Normal file
33
lib/coffee_script/scope.rb
Normal file
|
@ -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
|
34
lib/coffee_script/value.rb
Normal file
34
lib/coffee_script/value.rb
Normal file
|
@ -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
|
Loading…
Reference in a new issue