diff vendor/plugins/coderay-0.9.2/lib/coderay/scanners/scheme.rb @ 0:513646585e45

* Import Redmine trunk SVN rev 3859
author Chris Cannam
date Fri, 23 Jul 2010 15:52:44 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/plugins/coderay-0.9.2/lib/coderay/scanners/scheme.rb	Fri Jul 23 15:52:44 2010 +0100
@@ -0,0 +1,145 @@
+module CodeRay
+  module Scanners
+
+    # Scheme scanner for CodeRay (by closure).
+    # Thanks to murphy for putting CodeRay into public.
+    class Scheme < Scanner
+      
+      # TODO: function defs
+      # TODO: built-in functions
+      
+      register_for :scheme
+      file_extension 'scm'
+
+      CORE_FORMS = %w[
+        lambda let let* letrec syntax-case define-syntax let-syntax
+        letrec-syntax begin define quote if or and cond case do delay
+        quasiquote set! cons force call-with-current-continuation call/cc
+      ]
+
+      IDENT_KIND = CaseIgnoringWordList.new(:ident).
+        add(CORE_FORMS, :reserved)
+      
+      #IDENTIFIER_INITIAL = /[a-z!@\$%&\*\/\:<=>\?~_\^]/i
+      #IDENTIFIER_SUBSEQUENT = /#{IDENTIFIER_INITIAL}|\d|\.|\+|-/
+      #IDENTIFIER = /#{IDENTIFIER_INITIAL}#{IDENTIFIER_SUBSEQUENT}*|\+|-|\.{3}/
+      IDENTIFIER = /[a-zA-Z!@$%&*\/:<=>?~_^][\w!@$%&*\/:<=>?~^.+\-]*|[+-]|\.\.\./
+      DIGIT = /\d/
+      DIGIT10 = DIGIT
+      DIGIT16 = /[0-9a-f]/i
+      DIGIT8 = /[0-7]/
+      DIGIT2 = /[01]/
+      RADIX16 = /\#x/i
+      RADIX8 = /\#o/i
+      RADIX2 = /\#b/i
+      RADIX10 = /\#d/i
+      EXACTNESS = /#i|#e/i
+      SIGN = /[\+-]?/
+      EXP_MARK = /[esfdl]/i
+      EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/
+      SUFFIX = /#{EXP}?/
+      PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/
+      PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/
+      PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/
+      PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/
+      UINT10 = /#{DIGIT10}+#*/
+      UINT16 = /#{DIGIT16}+#*/
+      UINT8 = /#{DIGIT8}+#*/
+      UINT2 = /#{DIGIT2}+#*/
+      DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/
+      UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/
+      UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/
+      UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/
+      UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/
+      REAL10 = /#{SIGN}#{UREAL10}/
+      REAL16 = /#{SIGN}#{UREAL16}/
+      REAL8 = /#{SIGN}#{UREAL8}/
+      REAL2 = /#{SIGN}#{UREAL2}/
+      IMAG10 = /i|#{UREAL10}i/
+      IMAG16 = /i|#{UREAL16}i/
+      IMAG8 = /i|#{UREAL8}i/
+      IMAG2 = /i|#{UREAL2}i/
+      COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/
+      COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/
+      COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/
+      COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/
+      NUM10 = /#{PREFIX10}?#{COMPLEX10}/
+      NUM16 = /#{PREFIX16}#{COMPLEX16}/
+      NUM8 = /#{PREFIX8}#{COMPLEX8}/
+      NUM2 = /#{PREFIX2}#{COMPLEX2}/
+      NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/
+    
+    private
+      def scan_tokens tokens,options
+        
+        state = :initial
+        ident_kind = IDENT_KIND
+        
+        until eos?
+          kind = match = nil
+          
+          case state
+          when :initial
+            if scan(/ \s+ | \\\n /x)
+              kind = :space
+            elsif scan(/['\(\[\)\]]|#\(/)
+              kind = :operator_fat
+            elsif scan(/;.*/)
+              kind = :comment
+            elsif scan(/#\\(?:newline|space|.?)/)
+              kind = :char
+            elsif scan(/#[ft]/)
+              kind = :pre_constant
+            elsif scan(/#{IDENTIFIER}/o)
+              kind = ident_kind[matched]
+            elsif scan(/\./)
+              kind = :operator
+            elsif scan(/"/)
+              tokens << [:open, :string]
+              state = :string
+              tokens << ['"', :delimiter]
+              next
+            elsif scan(/#{NUM}/o) and not matched.empty?
+              kind = :integer
+            elsif getch
+              kind = :error
+            end
+            
+          when :string
+            if scan(/[^"\\]+/) or scan(/\\.?/)
+              kind = :content
+            elsif scan(/"/)
+              tokens << ['"', :delimiter]
+              tokens << [:close, :string]
+              state = :initial
+              next
+            else
+              raise_inspect "else case \" reached; %p not handled." % peek(1),
+                tokens, state
+            end
+            
+          else
+            raise "else case reached"
+          end
+          
+          match ||= matched
+          if $CODERAY_DEBUG and not kind
+            raise_inspect 'Error token %p in line %d' %
+            [[match, kind], line], tokens
+          end
+          raise_inspect 'Empty token', tokens, state unless match
+          
+          tokens << [match, kind]
+          
+        end  # until eos
+        
+        if state == :string
+          tokens << [:close, :string]
+        end
+        
+        tokens
+        
+      end #scan_tokens
+    end #class
+  end #module scanners
+end #module coderay
\ No newline at end of file