Permalink
Browse files

A little bit of refactor, add smalltalk syntax

  • Loading branch information...
1 parent 1536ae9 commit f490840763bc3360b780647a3759d886acf9fa65 @manveru committed Jun 25, 2009
Showing with 79 additions and 29 deletions.
  1. +4 −1 bin/sloc
  2. +26 −25 lib/sloc.rb
  3. +15 −3 lib/sloc/counter.rb
  4. +11 −0 lib/sloc/grammar/javascript.tt
  5. +23 −0 lib/sloc/grammar/smalltalk.tt
View
@@ -1,5 +1,6 @@
#!/usr/bin/env ruby
+require 'pathname'
require 'optparse'
require 'ostruct'
@@ -13,7 +14,9 @@ require_sloc = lambda{
begin
require 'sloc'
rescue LoadError
- $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
+ file = Pathname(__FILE__)
+ file = file.readlink if file.symlink?
+ $LOAD_PATH.unshift(File.expand_path('../../lib', file))
require 'sloc'
end
}
View
@@ -7,17 +7,25 @@
module SLOC
GRAMMAR_ROOT = File.expand_path('../sloc/grammar/', __FILE__)
- COUNTERS_NAMES = {
- :ruby => 'RubyParser',
- :sh => 'ShParser',
- :lisp => 'LispParser',
- }
+ SYNTAX_LIST = {}
+ COUNTER_CACHE = {}
module_function
- def counter_for(type)
- if name = COUNTERS_NAMES[type]
- Counter.new(type.to_s, name)
+ def syntax(name, ext, shebang = nil)
+ SYNTAX_LIST[name] = [ext, shebang]
+ end
+
+ # name ext shebang
+ syntax :ruby, /\.(rb|rake)$/, /ruby/
+ syntax :sh, /\.(sh|zsh)/, /sh|zsh|bash/
+ syntax :lisp, /\.lisp/, /lisp|scheme|sbcl/
+ syntax :smalltalk, /\.st/, /gst/
+ syntax :javascript, /\.js/, /js/
+
+ def counter_for(name)
+ if found = SYNTAX_LIST[name]
+ COUNTER_CACHE[name] ||= Counter.new(name.to_s, "#{name.to_s.capitalize}Parser")
end
end
@@ -34,29 +42,26 @@ def glob(globname)
total
end
- def file(filename, override_type = nil)
+ def file(filename, override_name = nil)
path = Pathname(filename.to_s)
path = path.readlink if path.symlink?
return unless path.file?
- type = override_type || detect_ext(path) || detect_shebang(path)
+ name = override_name || detect_ext(path) || detect_shebang(path)
- if counter = counter_for(type)
+ if counter = counter_for(name)
count = counter.file(path)
yield count if count && block_given?
count
end
end
def detect_ext(path)
- case path.extname
- when /\.(rb|rake)$/
- :ruby
- when /\.(sh|zsh)$/
- :sh
- when /\.(lisp)/
- :lisp
+ extname = path.extname
+
+ SYNTAX_LIST.find do |key, (ext, shebang)|
+ return key if extname =~ ext
end
end
@@ -65,14 +70,10 @@ def detect_shebang(path)
return unless shebang && shebang.valid_encoding?
if shebang =~ /^#!/
- case shebang
- when /ruby/
- :ruby
- when /zsh/
- :sh
- else
- warn "Unknown ext of %p, shebang detection for %p failed as well." % [path.to_s, shebang]
+ SYNTAX_LIST.find do |key, (ext, l_shebang)|
+ return key if shebang && shebang =~ l_shebang
end
+ warn "Unknown ext of %p, shebang detection for %p failed as well." % [path.to_s, shebang]
else
warn "Unknown ext of %p, no shebang found." % [path.to_s]
end
View
@@ -4,7 +4,7 @@ module SLOC
class Counter
def initialize(file, name)
Treetop.load(File.join(GRAMMAR_ROOT, "#{file}.tt"))
- @parser = Module.const_get(name).new
+ @parser_class = Module.const_get(name)
rescue NameError
Treetop.load(File.join(GRAMMAR_ROOT, "common.tt"))
retry
@@ -19,17 +19,29 @@ def glob(*files)
end
def file(file, total = Hash.new(0))
- SLOC.aggregate(@parser.parse(File.read(file)).count, total)
+ SLOC.aggregate(count(File.read(file)), total)
rescue => ex
p ex
raise "In #{file} - #{@parser.failure_reason}"
end
def string(string, total = Hash.new(0))
- SLOC.aggregate(@parser.parse(string).count, total)
+ SLOC.aggregate(count(string), total)
rescue => ex
p ex
raise @parser.failure_reason.dump
end
+
+ private
+
+ def count(string)
+ @parser = @parser_class.new
+ @parser.parse(string).count
+ ensure
+ count_objects = ObjectSpace.count_objects
+ total, free = count_objects.values_at(:TOTAL, :FREE)
+ @parser = nil
+ GC.start if free < 524288
+ end
end
end
@@ -0,0 +1,11 @@
+grammar Javascript
+ include Common
+
+ rule file
+ lines
+ end
+
+ rule comment_token
+ '//'
+ end
+end
@@ -0,0 +1,23 @@
+grammar Smalltalk
+ include Common
+
+ rule file
+ lines
+ end
+
+ rule code
+ ('$"' / [^"])+ {
+ def count
+ {code: text_value.count("\n")}
+ end
+ }
+ end
+
+ rule comment
+ '"' (!'"' .)* '"' {
+ def count
+ {comment: text_value.count("\n")}
+ end
+ }
+ end
+end

0 comments on commit f490840

Please sign in to comment.