-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improvements to the REPL (ifancy) backwards compatibility has been pr…
…eserved. A better API for loading plugins will come shortly to allow for easier adding of user plugins. If coderay is present, syntax hilighting will be used on returned values. Features have been implemented, documentation to come.
- Loading branch information
Showing
4 changed files
with
300 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# This is basically a big hacked version of CodeRay::Scanners::Ruby, | ||
# since the language semantics are the same in many areas, the patterns | ||
# are where it will differ the most if i am correct. | ||
|
||
module CodeRay | ||
module Scanners | ||
|
||
class Fancy < Scanner | ||
|
||
register_for :fancy | ||
file_exstension 'fy' | ||
|
||
autoload :Patterns, File.expand_path(File.dirname(__FILE__)) + "/coderay/patterns" | ||
autoload :StringState, File.expand_path(File.dirname(__FILE__)) + "/coderay/string_state" | ||
|
||
def interpreted_string_state | ||
StringState.new :string, true, ?" | ||
end | ||
|
||
protected | ||
|
||
def setup | ||
@state = :initial | ||
end | ||
|
||
def scan_tokens encoder, options | ||
state, heredocs = options[:state] || @state | ||
heredocs = heredocs.dup if heredocs.is_a? Array | ||
|
||
if state && state.instance_of? StringState | ||
encoder.begin_group state.type | ||
end | ||
|
||
last_state = nil | ||
|
||
method_call_expected = false | ||
value_expected = true | ||
|
||
inline_block_stack = nil | ||
inline_block_curly_depth = 0 | ||
|
||
if heredocs | ||
state = heredocs.shift | ||
encoder.begin_group state.type | ||
heredocs = nil if heredocs.empty? | ||
end | ||
|
||
patters = Patterns | ||
|
||
unicode = string.respond_to? :encoding && string.encoding.name == 'UTF-8' | ||
|
||
until eos? | ||
|
||
if state.instance_of? ::Symbol | ||
|
||
if match = scan(/[ \t\f\v]+/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# encoding: utf-8 | ||
module CodeRay | ||
module Scanners | ||
|
||
# Fancy scanner by swarley. | ||
class Fancy < Scanner | ||
|
||
register_for :fancy | ||
file_extension 'fy' | ||
|
||
SPECIAL_FORMS = %w[ | ||
def throw try catch class | ||
] # :nodoc: | ||
|
||
CORE_FORMS = %w[ | ||
+ - > < == != >= <= % ** * = && || =~ | ||
] # :nodoc: | ||
|
||
PREDEFINED_CONSTANTS = %w[ | ||
true false nil | ||
] # :nodoc: | ||
|
||
IDENT_KIND = WordList.new(:ident). | ||
add(SPECIAL_FORMS, :keyword). | ||
add(CORE_FORMS, :keyword). | ||
add(PREDEFINED_CONSTANTS, :predefined_constant) | ||
|
||
KEYWORD_NEXT_TOKEN_KIND = WordList.new(nil). | ||
add(%w[ def defn defn- definline defmacro defmulti defmethod defstruct defonce declare ], :function). | ||
add(%w[ ns ], :namespace). | ||
add(%w[ defprotocol defrecord ], :class) | ||
|
||
BASIC_IDENTIFIER = /[a-zA-Z$%*\/_+!?&<>\-=]=?[a-zA-Z0-9$&*+!\/_?<>\-\#]*/ | ||
CLASS_IDENTIFIER = /[A-Z]+[A-Za-z0-9]*|[A-Z]+[A-Za-z0-9]\:\:|\:\:[A-Z]+[A-Za-z0-9]*/ | ||
IDENTIFIER = /(?!-\d)(?:(?:#{BASIC_IDENTIFIER}\.)*#{BASIC_IDENTIFIER}(?:\/#{BASIC_IDENTIFIER})?\.?)|\.\.?/ | ||
SYMBOL = /\'[A-Za-z]/o | ||
DIGIT = /\d+/ | ||
DIGIT10 = DIGIT | ||
DIGIT16 = /[0-9a-f]/i | ||
DIGIT8 = /[0-7]/ | ||
DIGIT2 = /[01]/ | ||
DECIMAL = /#{DIGIT}\.#{DIGIT}|-#{DIGIT}\.#{DIGIT}/ | ||
NUM = /(?:\-)*(?:#{DIGIT}|#{DIGIT16}|#{DIGIT8}|#{DIGIT2}|#{DECIMAL})/ | ||
MESSAGE = /[A-Za-z0-9\&\_]+?(?:\:|\?\:)/ | ||
CAPTURE = /\|.+?\|/ | ||
protected | ||
|
||
def scan_tokens encoder, options | ||
|
||
state = :initial | ||
kind = nil | ||
|
||
until eos? | ||
|
||
case state | ||
when :initial | ||
if match = scan(/ \s+ | \n | , /x) | ||
encoder.text_token match, :space | ||
elsif match = scan(/\#.+?$/) | ||
encoder.text_token match, :comment | ||
elsif match = scan(/\{|\}|\@\{|\[|\]|\(|\)/) | ||
encoder.text_token match, :operator | ||
elsif match = scan(Regexp.new((%W(+ - @ > < == != >= <= % ** * = && || =~).map {|x| Regexp.escape x }).join '|')) | ||
encoder.text_token match, :operator | ||
elsif match = scan(/\.|\$/) | ||
encoder.text_token match, :predefined_constant | ||
elsif match = scan(CAPTURE) | ||
encoder.text_token match, :predefined_constant | ||
elsif match = scan(CLASS_IDENTIFIER) | ||
encoder.text_token match, :constant | ||
elsif match = scan(/\:\:/) | ||
encoder.text_token match, :constant | ||
elsif match = scan(MESSAGE) | ||
encoder.text_token match, :keyword | ||
elsif match = scan(/#{IDENTIFIER}/o) | ||
kind = IDENT_KIND[match] | ||
encoder.text_token match, kind | ||
if rest? && kind == :keyword | ||
if kind = KEYWORD_NEXT_TOKEN_KIND[match] | ||
encoder.text_token match, :space if match = scan(/\s+/o) | ||
encoder.text_token match, kind if match = scan(/#{IDENTIFIER}/o) | ||
end | ||
end | ||
elsif match = scan(MESSAGE) | ||
encoder.text_token match, :keyword | ||
elsif match = scan(/#{SYMBOL}/o) | ||
encoder.text_token match, :symbol | ||
elsif match = scan(/\./) | ||
encoder.text_token match, :operator | ||
elsif match = scan(/ \# \^ #{IDENTIFIER} /ox) | ||
encoder.text_token match, :type | ||
elsif match = scan(/ (\#)? " /x) | ||
state = self[1] ? :regexp : :string | ||
encoder.begin_group state | ||
encoder.text_token match, :delimiter | ||
elsif match = scan(/#{NUM}/o) and not matched.empty? | ||
encoder.text_token match, match[/[.e\/]/i] ? :float : :integer | ||
else | ||
encoder.text_token getch, :error | ||
end | ||
|
||
when :string, :regexp | ||
if match = scan(/[^"\\]+|\\.?/) | ||
encoder.text_token match, :content | ||
elsif match = scan(/"/) | ||
encoder.text_token match, :delimiter | ||
encoder.end_group state | ||
state = :initial | ||
else | ||
raise_inspect "else case \" reached; %p not handled." % peek(1), | ||
encoder, state | ||
end | ||
|
||
else | ||
raise 'else case reached' | ||
|
||
end | ||
|
||
end | ||
|
||
if [:string, :regexp].include? state | ||
encoder.end_group state | ||
end | ||
|
||
encoder | ||
|
||
end | ||
end | ||
end | ||
end |