adding soaked method calls, with caching

This commit is contained in:
Jeremy Ashkenas 2010-01-24 12:52:15 -05:00
parent d728c3d669
commit 817e8deb27
6 changed files with 63 additions and 4 deletions

View File

@ -0,0 +1,4 @@
Ported from Nicholas Zakas' collection of computer science fundamentals, written
in JavaScript. Originals available here:
http://github.com/nzakas/computer-science-in-javascript

View File

@ -0,0 +1,25 @@
# Uses a binary search algorithm to locate a value in the specified array.
binary_search: items, value =>
start: 0
stop: items.length - 1
pivot: Math.floor((start + stop) / 2)
while items[pivot] isnt value and start < stop
# Adjust the search area.
stop: pivot - 1 if value < items[pivot]
start: pivot + 1 if value > items[pivot]
# Recalculate the pivot.
pivot: Math.floor((stop + start) / 2)
# Make sure we've found the correct value.
if items[pivot] is value then pivot else -1
# Test the function.
print(2 is binary_search([10, 20, 30, 40, 50], 30))
print(4 is binary_search([-97, 35, 67, 88, 1200], 1200))
print(0 is binary_search([0, 45, 70], 0))
print(-1 is binary_search([0, 45, 70], 10))

View File

@ -0,0 +1,11 @@
# A bubble sort implementation, sorting the given array in-place.
bubble_sort: list =>
for i in [0...list.length]
for j in [0...list.length - i]
[list[j], list[j+1]]: [list[j+1], list[j]] if list[j] > list[j+1]
list
# Test the function.
print(bubble_sort([3, 2, 1]).join(' ') is '1 2 3')
print(bubble_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9')

View File

@ -332,6 +332,9 @@ module CoffeeScript
children :base, :properties
attr_reader :last, :source
# Soak up undefined properties and call attempts.
SOAK = " == undefined ? undefined : "
def initialize(base, properties=[])
@base, @properties = base, [properties].flatten
end
@ -375,14 +378,19 @@ module CoffeeScript
props.each do |prop|
if prop.is_a?(AccessorNode) && prop.soak
soaked = true
parts[-1] << " == undefined ? undefined : #{baseline += prop.compile(o)}"
if @base.is_a?(CallNode) && prop == props.first
temp = o[:scope].free_variable
parts[-1] = "(#{temp} = #{baseline})#{SOAK}#{baseline = temp.to_s + prop.compile(o)}"
else
parts[-1] << "#{SOAK}#{baseline += prop.compile(o)}"
end
else
parts << prop.compile(o)
end
end
@last = parts.last
@source = parts.length > 1 ? parts[0...-1].join('') : nil
code = parts.join('')
code = parts.join('').gsub(')())', '()))')
write(soaked ? "(#{code})" : code)
end
end

View File

@ -41,4 +41,14 @@ obj: {
print(obj?.prop is "hello")
print(obj?.prop?.non?.existent?.property is undefined)
print(obj?.prop?.non?.existent?.property is undefined)
# Soaks and caches method calls as well.
arr: ["--", "----"]
print(arr.pop()?.length is 4)
print(arr.pop()?.length is 2)
print(arr.pop()?.length is undefined)
print(arr.pop()?.length?.non?.existent()?.property is undefined)

View File

@ -6,7 +6,8 @@ class ExecutionTest < Test::Unit::TestCase
SOURCES = [
'test/fixtures/execution/*.coffee',
'examples/beautiful_code/*.coffee'
'examples/beautiful_code/*.coffee',
'examples/computer_science/*.coffee'
]
# This is by far the most important test. It evaluates all of the