diff --git a/.gitignore b/.gitignore index 71239be2..90d94706 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ -Gemfile.lock +/Gemfile.lock .bundle/ benchmark/ lib/linguist/samples.json +/grammars +/node_modules diff --git a/.travis.yml b/.travis.yml index a964fa81..7b013349 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,12 @@ before_install: - git fetch origin master:master - git fetch origin v2.0.0:v2.0.0 - git fetch origin test/attributes:test/attributes + - git fetch origin test/master:test/master - sudo apt-get install libicu-dev -y rvm: - 1.9.3 - 2.0.0 - - 2.1.1 + - 2.1 + - 2.2 notifications: disabled: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..ee13ae71 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,31 @@ +## Contributing + +The majority of contributions won't need to touch any Ruby code at all. The [master language list][languages] is just a YAML configuration file. + +Almost all bug fixes or new language additions should come with some additional code samples. Just drop them under [`samples/`][samples] in the correct subdirectory and our test suite will automatically test them. In most cases you shouldn't need to add any new assertions. + +### My code is detected as the wrong language + +This can usually be solved either by adding a new filename or file name extension to the language's entry in [`languages.yml`][languages] or adding more [samples][samples] for your language to the repository to make Linguist's classifier smarter. + +### Syntax highlighting looks wrong + +Assuming your code is being detected as the right language (see above), in most cases this is due to a bug in the language grammar rather than a bug in Linguist. [`grammars.yml`][grammars] lists all the grammars we use for syntax highlighting on github.com. Find the one corresponding to your code's programming language and submit a bug report upstream. + +You can also try to fix the bug yourself and submit a Pull Request. [This piece from TextMate's documentation](http://manual.macromates.com/en/language_grammars) offers a good introduction on how to work with TextMate-compatible grammars. + +Once the bug has been fixed upstream, please let us know and we'll pick it up for GitHub. + +### I want to add support for the `X` programming language + +Great! You'll need to: + +0. Add an entry for your language to [`languages.yml`][languages]. +0. Add a grammar for your language to [`grammars.yml`][grammars] by running `script/download-grammars --add URL`. Please only add grammars that have a license that permits redistribution. +0. Add samples for your language to the [samples directory][samples]. + +We try only to add languages once they have some usage on GitHub, so please note in-the-wild usage examples in your pull request. In most cases we prefer that languages already be in use in hundreds of repositories before supporting them in Linguist. + +[grammars]: /grammars.yml +[languages]: /lib/linguist/languages.yml +[samples]: /samples diff --git a/Gemfile b/Gemfile index 851fabc2..481a4c6e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,4 @@ source 'https://rubygems.org' -gemspec +gemspec :name => "github-linguist" +gemspec :name => "github-linguist-grammars" +gem 'test-unit', require: false if RUBY_VERSION >= '2.2' diff --git a/README.md b/README.md index 94430f4d..5eaa2f20 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # Linguist -We use this library at GitHub to detect blob languages, highlight code, ignore binary files, suppress generated files in diffs, and generate language breakdown graphs. +We use this library at GitHub to detect blob languages, ignore binary files, suppress generated files in diffs, and generate language breakdown graphs. + +Tips for filing issues and creating pull requests can be found in [`CONTRIBUTING.md`](/CONTRIBUTING.md). ## Features ### Language detection -Linguist defines a list of all languages known to GitHub in a [yaml file](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml). In order for a file to be highlighted, a language and a lexer must be defined there. +Linguist defines a list of all languages known to GitHub in a [yaml file](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml). Most languages are detected by their file extension. For disambiguating between files with common extensions, we first apply some common-sense heuristics to pick out obvious languages. After that, we use a [statistical @@ -24,7 +26,9 @@ See [lib/linguist/language.rb](https://github.com/github/linguist/blob/master/li ### Syntax Highlighting -The actual syntax highlighting is handled by our Pygments wrapper, [pygments.rb](https://github.com/tmm1/pygments.rb). It also provides a [Lexer abstraction](https://github.com/tmm1/pygments.rb/blob/master/lib/pygments/lexer.rb) that determines which highlighter should be used on a file. +Syntax highlighting in GitHub is performed using TextMate-compatible grammars. These are the same grammars that TextMate, Sublime Text and Atom use. + +Every language in `languages.yml` is mapped to its corresponding TM `scope`. This scope will be used when picking up a grammar for highlighting. **When adding a new language to Linguist, please add its corresponding scope too (assuming there's an existing TextMate bundle, Sublime Text package, or Atom package) so syntax highlighting works for it**. ### Stats @@ -143,14 +147,6 @@ To run the tests: bundle exec rake test -## Contributing - -The majority of contributions won't need to touch any Ruby code at all. The [master language list](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml) is just a YAML configuration file. - -We try to only add languages once they have some usage on GitHub, so please note in-the-wild usage examples in your pull request. - -Almost all bug fixes or new language additions should come with some additional code samples. Just drop them under [`samples/`](https://github.com/github/linguist/tree/master/samples) in the correct subdirectory and our test suite will automatically test them. In most cases you shouldn't need to add any new assertions. - ### A note on language extensions Linguist has a number of methods available to it for identifying the language of a particular file. The initial lookup is based upon the extension of the file, possible file extensions are defined in an array called `extensions`. Take a look at this example for example for `Perl`: diff --git a/Rakefile b/Rakefile index 8a044135..470dcec9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,8 +1,8 @@ require 'bundler/setup' -require 'json' require 'rake/clean' require 'rake/testtask' require 'yaml' +require 'yajl' task :default => :test @@ -20,19 +20,23 @@ end task :samples do require 'linguist/samples' - require 'yajl' - data = Linguist::Samples.data - json = Yajl::Encoder.encode(data, :pretty => true) - File.open('lib/linguist/samples.json', 'w') { |io| io.write json } + json = Yajl.dump(Linguist::Samples.data, :pretty => true) + File.write 'lib/linguist/samples.json', json end task :build_gem => :samples do languages = YAML.load_file("lib/linguist/languages.yml") - File.write("lib/linguist/languages.json", JSON.dump(languages)) + File.write("lib/linguist/languages.json", Yajl.dump(languages)) `gem build github-linguist.gemspec` File.delete("lib/linguist/languages.json") end +task :build_grammars_gem do + rm_rf "grammars" + sh "script/download-grammars" + sh "gem", "build", "github-linguist-grammars.gemspec" +end + namespace :benchmark do benchmark_path = "benchmark/results" @@ -72,11 +76,11 @@ namespace :benchmark do reference_file = ENV["REFERENCE"] candidate_file = ENV["CANDIDATE"] - reference = JSON.parse(File.read(reference_file)) + reference = Yajl.load(File.read(reference_file)) reference_counts = Hash.new(0) reference.each { |filename, language| reference_counts[language] += 1 } - candidate = JSON.parse(File.read(candidate_file)) + candidate = Yajl.load(File.read(candidate_file)) candidate_counts = Hash.new(0) candidate.each { |filename, language| candidate_counts[language] += 1 } @@ -126,14 +130,12 @@ namespace :classifier do def each_public_gist require 'open-uri' - require 'json' - url = "https://api.github.com/gists/public" loop do resp = open(url) url = resp.meta['link'][/<([^>]+)>; rel="next"/, 1] - gists = JSON.parse(resp.read) + gists = Yajl.load(resp.read) for gist in gists for filename, attrs in gist['files'] diff --git a/github-linguist-grammars.gemspec b/github-linguist-grammars.gemspec new file mode 100644 index 00000000..429b3ff1 --- /dev/null +++ b/github-linguist-grammars.gemspec @@ -0,0 +1,14 @@ +require File.expand_path('../lib/linguist/version', __FILE__) + +Gem::Specification.new do |s| + s.name = 'github-linguist-grammars' + s.version = Linguist::VERSION + s.summary = "Language grammars for use with github-linguist" + + s.authors = "GitHub" + s.homepage = "https://github.com/github/linguist" + + s.files = ['lib/linguist/grammars.rb'] + Dir['grammars/*'] + + s.add_development_dependency 'plist', '~>3.1' +end diff --git a/github-linguist.gemspec b/github-linguist.gemspec index 6a06a6f2..578e823c 100644 --- a/github-linguist.gemspec +++ b/github-linguist.gemspec @@ -10,16 +10,14 @@ Gem::Specification.new do |s| s.homepage = "https://github.com/github/linguist" s.license = "MIT" - s.files = Dir['lib/**/*'] + s.files = Dir['lib/**/*'] - ['lib/linguist/grammars.rb'] s.executables << 'linguist' s.add_dependency 'charlock_holmes', '~> 0.7.3' s.add_dependency 'escape_utils', '~> 1.0.1' - s.add_dependency 'mime-types', '~> 1.19' - s.add_dependency 'pygments.rb', '~> 0.6.0' - s.add_dependency 'rugged', '~> 0.21.1b2' + s.add_dependency 'mime-types', '>= 1.19' + s.add_dependency 'rugged', '~> 0.22.0b4' - s.add_development_dependency 'json' s.add_development_dependency 'mocha' s.add_development_dependency 'pry' s.add_development_dependency 'rake' diff --git a/grammars.yml b/grammars.yml new file mode 100644 index 00000000..fbf087d3 --- /dev/null +++ b/grammars.yml @@ -0,0 +1,410 @@ +--- +http://svn.edgewall.org/repos/genshi/contrib/textmate/Genshi.tmbundle/Syntaxes/Markup%20Template%20%28XML%29.tmLanguage: +- text.xml.genshi +http://svn.textmate.org/trunk/Review/Bundles/BlitzMax.tmbundle: +- source.blitzmax +http://svn.textmate.org/trunk/Review/Bundles/Cython.tmbundle: +- source.cython +http://svn.textmate.org/trunk/Review/Bundles/F%20Sharp.tmbundle: +- source.fsharp +http://svn.textmate.org/trunk/Review/Bundles/Forth.tmbundle: +- source.forth +http://svn.textmate.org/trunk/Review/Bundles/Parrot.tmbundle: +- source.parrot.pir +http://svn.textmate.org/trunk/Review/Bundles/Ruby%20Sass.tmbundle: +- source.sass +http://svn.textmate.org/trunk/Review/Bundles/SecondLife%20LSL.tmbundle: +- source.lsl +http://svn.textmate.org/trunk/Review/Bundles/VHDL.tmbundle: +- source.vhdl +http://svn.textmate.org/trunk/Review/Bundles/XQuery.tmbundle: +- source.xquery +https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz: +- source.systemverilog +- source.ucfconstraints +https://bitbucket.org/bitlang/sublime_cobol/raw/b0e9c44ac5f7a2fb553421aa986b35854cbfda4a/COBOL.tmLanguage: +- source.cobol +https://fan.googlecode.com/hg-history/Build%201.0.55/adm/tools/textmate/Fan.tmbundle/Syntaxes/Fan.tmLanguage: +- source.fan +https://github.com/AlanQuatermain/go-tmbundle: +- source.go +https://github.com/Anomareh/PHP-Twig.tmbundle: +- text.html.twig +https://github.com/Cirru/sublime-cirru/raw/master/Cirru.tmLanguage: +- source.cirru +https://github.com/Cykey/Sublime-Logos: +- source.logos +https://github.com/Drako/SublimeBrainfuck/raw/master/Brainfuck.tmLanguage: +- source.bf +https://github.com/JohnNilsson/awk-sublime/raw/master/AWK.tmLanguage: +- source.awk +https://github.com/JonBons/Sublime-SQF-Language: +- source.sqf +https://github.com/MarioRicalde/SCSS.tmbundle: +- source.scss +https://github.com/Oldes/Sublime-REBOL: +- source.rebol +https://github.com/PogiNate/Sublime-Inform: +- source.Inform7 +https://github.com/Red-Nova-Technologies/autoitv3-tmbundle: +- source.autoit.3 +https://github.com/SalGnt/Sublime-VimL: +- source.viml +https://github.com/Shammah/boo-sublime/raw/master/Boo.tmLanguage: +- source.boo +https://github.com/SublimeText/ColdFusion: +- source.cfscript +- source.cfscript.cfc +- text.cfml.basic +- text.html.cfm +https://github.com/SublimeText/NSIS: +- source.nsis +https://github.com/Varriount/NimLime: +- source.nimrod +- source.nimrod_filter +- source.nimrodcfg +https://github.com/angryant0007/VBDotNetSyntax: +- source.vbnet +https://github.com/aroben/ada.tmbundle/raw/c45eed4d5f98fe3bcbbffbb9e436601ab5bbde4b/Syntaxes/Ada.plist: +- source.ada +https://github.com/aroben/ruby.tmbundle@4636a3023153c3034eb6ffc613899ba9cf33b41f: +- source.ruby +- text.html.erb +https://github.com/asbjornenge/Docker.tmbundle: +- source.dockerfile +https://github.com/atom/language-clojure: +- source.clojure +https://github.com/atom/language-coffee-script: +- source.coffee +- source.litcoffee +https://github.com/atom/language-csharp: +- source.cs +- source.csx +- source.nant-build +https://github.com/atom/language-javascript: +- source.js +- source.js.regexp +https://github.com/atom/language-python: +- source.python +- source.regexp.python +- text.python.traceback +https://github.com/atom/language-shellscript: +- source.shell +- text.shell-session +https://github.com/austinwagner/sublime-sourcepawn: +- source.sp +https://github.com/bfad/Sublime-Lasso: +- file.lasso +https://github.com/bholt/chapel-tmbundle: +- source.chapel +https://github.com/brandonwamboldt/sublime-nginx: +- source.nginx +https://github.com/bro/bro-sublime: +- source.bro +https://github.com/carsonoid/sublime_man_page_support/raw/master/man-groff.tmLanguage: +- text.groff +https://github.com/ccreutzig/sublime-MuPAD: +- source.mupad +https://github.com/cdwilson/nesC.tmbundle: +- source.nesc +https://github.com/christophevg/racket-tmbundle: +- source.racket +https://github.com/clemos/haxe-sublime-bundle: +- source.erazor +- source.haxe.2 +- source.hss.1 +- source.hxml +- source.nmml +https://github.com/cucumber/cucumber-tmbundle: +- source.ruby.rspec.cucumber.steps +- text.gherkin.feature +https://github.com/daaain/Handlebars/raw/master/Handlebars.tmLanguage: +- text.html.handlebars +https://github.com/davidpeckham/powershell.tmbundle: +- source.powershell +https://github.com/davidrios/jade-tmbundle: +- source.jade +- source.pyjade +https://github.com/elixir-lang/elixir-tmbundle: +- source.elixir +- text.elixir +- text.html.elixir +https://github.com/ericzou/ebundles/raw/master/Bundles/MSDOS%20batch%20file.tmbundle/Syntaxes/MSDOS%20batch%20file.tmLanguage: +- source.dosbatch +https://github.com/euler0/sublime-glsl/raw/master/GLSL.tmLanguage: +- source.glsl +https://github.com/fancy-lang/fancy-tmbundle: +- source.fancy +https://github.com/gingerbeardman/monkey.tmbundle: +- source.monkey +https://github.com/guillermooo/dart-sublime-bundle/raw/master/Dart.tmLanguage: +- source.dart +https://github.com/harrism/sublimetext-cuda-cpp/raw/master/cuda-c%2B%2B.tmLanguage: +- source.cuda-c++ +https://github.com/hww3/pike-textmate: +- source.pike +https://github.com/jeancharles-roger/ceylon-sublimetext/raw/master/Ceylon.tmLanguage: +- source.ceylon +https://github.com/jfairbank/Sublime-Text-2-OpenEdge-ABL: +- source.abl +https://github.com/jhasse/sublime-rust: +- source.rust +https://github.com/johanasplund/sublime-befunge/raw/master/Befunge-93.tmLanguage: +- source.befunge +https://github.com/joshaven/RDoc.tmbundle: +- text.rdoc +https://github.com/jpcamara/Textmate-Gosu-Bundle/raw/master/Gosu.tmbundle/Syntaxes/Gosu.tmLanguage: +- source.gosu.2 +https://github.com/kswedberg/jquery-tmbundle: +- source.js.jquery +https://github.com/laughedelic/sublime-idris/raw/master/Idris.tmLanguage: +- source.idris +https://github.com/lavrton/sublime-better-typescript: +- source.ts +https://github.com/leafo/moonscript-tmbundle: +- source.moonscript +https://github.com/lunixbochs/x86-assembly-textmate-bundle: +- source.asm.x86 +https://github.com/macekond/Alloy.tmbundle: +- source.alloy +https://github.com/mads379/opa.tmbundle: +- source.opa +https://github.com/mads379/scala.tmbundle: +- source.sbt +- source.scala +https://github.com/marconi/mako-tmbundle: +- text.html.mako +https://github.com/mattfoster/gnuplot-tmbundle: +- source.gnuplot +https://github.com/mgalloy/idl.tmbundle: +- source.idl +- source.idl-dlm +- text.idl-idldoc +https://github.com/michaeledgar/protobuf-tmbundle: +- source.protobuf +https://github.com/mkolosick/Sublime-Coq/raw/master/Coq.tmLanguage: +- source.coq +https://github.com/mokus0/Agda.tmbundle: +- source.agda +https://github.com/nanoant/Julia.tmbundle: +- source.julia +https://github.com/nanoant/assembly.tmbundle/raw/master/Syntaxes/objdump%20C%2B%2B.tmLanguage: +- objdump.x86asm +https://github.com/nilium/ooc.tmbundle: +- source.ooc +https://github.com/paulmillr/LiveScript.tmbundle: +- source.livescript +https://github.com/pferruggiaro/sublime-tea: +- source.tea +https://github.com/puppet-textmate-bundle/puppet-textmate-bundle: +- source.puppet +https://github.com/pvl/abap.tmbundle: +- source.abap +https://github.com/scalate/Scalate.tmbundle: +- source.scaml +- text.html.ssp +https://github.com/shadanan/mathematica-tmbundle: +- source.mathematica +https://github.com/shellderp/sublime-robot-plugin: +- text.robot +https://github.com/simongregory/actionscript3-tmbundle: +- source.actionscript.3 +- text.html.asdoc +- text.xml.flex-config +https://github.com/skozlovf/Sublime-QML: +- source.qml +https://github.com/slash-lang/Slash.tmbundle: +- text.html.slash +https://github.com/slavapestov/factor/raw/master/misc/Factor.tmbundle/Syntaxes/Factor.tmLanguage: +- source.factor +https://github.com/slim-template/ruby-slim.tmbundle: +- text.slim +https://github.com/staltz/SublimeXtend: +- source.xtend +https://github.com/statatmbundle/Stata.tmbundle: +- source.mata +- source.stata +https://github.com/technosophos/Vala-TMBundle: +- source.vala +https://github.com/textmate/ant.tmbundle: +- text.xml.ant +https://github.com/textmate/antlr.tmbundle: +- source.antlr +https://github.com/textmate/apache.tmbundle: +- source.apache-config +- source.apache-config.mod_perl +https://github.com/textmate/applescript.tmbundle: +- source.applescript +https://github.com/textmate/asp.tmbundle: +- source.asp +- text.html.asp +https://github.com/textmate/bison.tmbundle: +- source.bison +https://github.com/textmate/c.tmbundle: +- source.c +- source.c++ +- source.c.platform +https://github.com/textmate/capnproto.tmbundle: +- source.capnp +https://github.com/textmate/cmake.tmbundle: +- source.cache.cmake +- source.cmake +https://github.com/textmate/cpp-qt.tmbundle: +- source.c++.qt +- source.qmake +https://github.com/textmate/css.tmbundle: +- source.css +https://github.com/textmate/d.tmbundle: +- source.d +https://github.com/textmate/diff.tmbundle: +- source.diff +https://github.com/textmate/dylan.tmbundle: +- source.dylan +- source.lid +- source.makegen +https://github.com/textmate/eiffel.tmbundle: +- source.eiffel +https://github.com/textmate/erlang.tmbundle: +- source.erlang +- text.html.erlang.yaws +https://github.com/textmate/fortran.tmbundle: +- source.fortran +- source.fortran.modern +https://github.com/textmate/gettext.tmbundle: +- source.po +https://github.com/textmate/graphviz.tmbundle: +- source.dot +https://github.com/textmate/groovy.tmbundle: +- source.groovy +https://github.com/textmate/haskell.tmbundle: +- source.haskell +- text.tex.latex.haskell +https://github.com/textmate/html.tmbundle: +- text.html.basic +https://github.com/textmate/ini.tmbundle: +- source.ini +https://github.com/textmate/io.tmbundle: +- source.io +https://github.com/textmate/java.tmbundle: +- source.java +- source.java-properties +- text.html.jsp +- text.junit-test-report +https://github.com/textmate/javadoc.tmbundle: +- text.html.javadoc +https://github.com/textmate/javascript-objective-j.tmbundle: +- source.js.objj +https://github.com/textmate/json.tmbundle: +- source.json +https://github.com/textmate/latex.tmbundle: +- text.bibtex +- text.log.latex +- text.tex +- text.tex.latex +- text.tex.latex.beamer +- text.tex.latex.memoir +https://github.com/textmate/less.tmbundle: +- source.css.less +https://github.com/textmate/lilypond.tmbundle: +- source.lilypond +https://github.com/textmate/lisp.tmbundle: +- source.lisp +https://github.com/textmate/logtalk.tmbundle: +- source.logtalk +https://github.com/textmate/lua.tmbundle: +- source.lua +https://github.com/textmate/make.tmbundle: +- source.makefile +https://github.com/textmate/markdown.tmbundle: +- text.html.markdown +https://github.com/textmate/matlab.tmbundle: +- source.matlab +- source.octave +https://github.com/textmate/maven.tmbundle: +- text.xml.pom +https://github.com/textmate/nemerle.tmbundle: +- source.nemerle +https://github.com/textmate/ninja.tmbundle: +- source.ninja +https://github.com/textmate/objective-c.tmbundle: +- source.objc +- source.objc++ +- source.objc.platform +- source.strings +https://github.com/textmate/ocaml.tmbundle: +- source.camlp4.ocaml +- source.ocaml +- source.ocamllex +- source.ocamlyacc +https://github.com/textmate/pascal.tmbundle: +- source.pascal +https://github.com/textmate/perl.tmbundle: +- source.perl +https://github.com/textmate/php-smarty.tmbundle: +- source.smarty +https://github.com/textmate/php.tmbundle: +- text.html.php +https://github.com/textmate/postscript.tmbundle: +- source.postscript +https://github.com/textmate/processing.tmbundle: +- source.processing +https://github.com/textmate/prolog.tmbundle: +- source.prolog +https://github.com/textmate/python-django.tmbundle: +- source.python.django +- text.html.django +https://github.com/textmate/r.tmbundle: +- source.r +- text.tex.latex.rd +https://github.com/textmate/restructuredtext.tmbundle: +- text.restructuredtext +https://github.com/textmate/ruby-haml.tmbundle: +- text.haml +https://github.com/textmate/ruby-on-rails-tmbundle: +- source.js.erb.rails +- source.ruby.rails +- source.ruby.rails.rjs +- source.sql.ruby +- text.html.erb.rails +https://github.com/textmate/scheme.tmbundle: +- source.scheme +https://github.com/textmate/scilab.tmbundle: +- source.scilab +https://github.com/textmate/sql.tmbundle: +- source.sql +https://github.com/textmate/standard-ml.tmbundle: +- source.cm +- source.ml +https://github.com/textmate/swift.tmbundle: +- source.swift +https://github.com/textmate/tcl.tmbundle: +- source.tcl +- text.html.tcl +https://github.com/textmate/text.tmbundle: +- text.plain +https://github.com/textmate/textile.tmbundle: +- text.html.textile +https://github.com/textmate/textmate.tmbundle: +- source.regexp.oniguruma +- source.tm-properties +https://github.com/textmate/thrift.tmbundle: +- source.thrift +https://github.com/textmate/toml.tmbundle: +- source.toml +https://github.com/textmate/verilog.tmbundle: +- source.verilog +https://github.com/textmate/xml.tmbundle: +- text.xml +- text.xml.xsl +https://github.com/textmate/yaml.tmbundle: +- source.yaml +https://github.com/tomas-stefano/smalltalk-tmbundle: +- source.smalltalk +https://github.com/vic/ioke-outdated/raw/master/share/TextMate/Ioke.tmbundle/Syntaxes/Ioke.tmLanguage: +- source.ioke +https://github.com/vkostyukov/kotlin-sublime-package: +- source.Kotlin +https://github.com/vmg/zephir-sublime: +- source.php.zephir +https://github.com/whitequark/llvm.tmbundle: +- source.llvm diff --git a/lib/linguist/blob_helper.rb b/lib/linguist/blob_helper.rb index 840ca75c..c368b4d0 100644 --- a/lib/linguist/blob_helper.rb +++ b/lib/linguist/blob_helper.rb @@ -2,7 +2,6 @@ require 'linguist/generated' require 'charlock_holmes' require 'escape_utils' require 'mime/types' -require 'pygments' require 'yaml' module Linguist @@ -147,6 +146,13 @@ module Linguist end end + # Public: Is the blob empty? + # + # Return true or false + def empty? + data.nil? || data == "" + end + # Public: Is the blob text? # # Return true or false @@ -193,10 +199,6 @@ module Linguist # Public: Is the blob safe to colorize? # - # We use Pygments for syntax highlighting blobs. Pygments - # can be too slow for very large blobs or for certain - # corner-case blobs. - # # Return true or false def safe_to_colorize? !large? && text? && !high_ratio_of_long_lines? @@ -204,9 +206,6 @@ module Linguist # Internal: Does the blob have a ratio of long lines? # - # These types of files are usually going to make Pygments.rb - # angry if we try to colorize them. - # # Return true or false def high_ratio_of_long_lines? return false if loc == 0 @@ -314,28 +313,9 @@ module Linguist @language ||= Language.detect(self) end - # Internal: Get the lexer of the blob. - # - # Returns a Lexer. - def lexer - language ? language.lexer : Pygments::Lexer.find_by_name('Text only') - end - # Internal: Get the TextMate compatible scope for the blob def tm_scope language && language.tm_scope end - - # Public: Highlight syntax of blob - # - # options - A Hash of options (defaults to {}) - # - # Returns html String - def colorize(options = {}) - return unless safe_to_colorize? - options[:options] ||= {} - options[:options][:encoding] ||= encoding - lexer.highlight(data, options) - end end end diff --git a/lib/linguist/generated.rb b/lib/linguist/generated.rb index 0f911c45..291fa8bd 100644 --- a/lib/linguist/generated.rb +++ b/lib/linguist/generated.rb @@ -51,26 +51,25 @@ module Linguist # # Return true or false def generated? - name == 'Gemfile.lock' || - minified_files? || - compiled_coffeescript? || - xcode_file? || - generated_parser? || - generated_net_docfile? || - generated_net_designer_file? || - generated_postscript? || - generated_protocol_buffer? || - generated_jni_header? || - composer_lock? || - node_modules? || - godeps? || - vcr_cassette? || - generated_by_zephir? + minified_files? || + compiled_coffeescript? || + xcode_file? || + generated_parser? || + generated_net_docfile? || + generated_net_designer_file? || + generated_postscript? || + generated_protocol_buffer? || + generated_jni_header? || + composer_lock? || + node_modules? || + godeps? || + vcr_cassette? || + generated_by_zephir? end # Internal: Is the blob an Xcode file? # - # Generated if the file extension is an Xcode + # Generated if the file extension is an Xcode # file extension. # # Returns true of false. @@ -265,4 +264,3 @@ module Linguist end end end - diff --git a/lib/linguist/grammars.rb b/lib/linguist/grammars.rb new file mode 100644 index 00000000..f6468280 --- /dev/null +++ b/lib/linguist/grammars.rb @@ -0,0 +1,13 @@ +# Note: This file is included in the github-linguist-grammars gem, not the +# github-linguist gem. + +module Linguist + module Grammars + # Get the path to the directory containing the language grammar JSON files. + # + # Returns a String. + def self.path + File.expand_path("../../../grammars", __FILE__) + end + end +end diff --git a/lib/linguist/heuristics.rb b/lib/linguist/heuristics.rb index e8b80524..f9f31a69 100644 --- a/lib/linguist/heuristics.rb +++ b/lib/linguist/heuristics.rb @@ -13,20 +13,34 @@ module Linguist # Returns an array of Languages or [] def self.find_by_heuristics(data, languages) if active? + result = [] + if languages.all? { |l| ["Objective-C", "C++", "C"].include?(l) } - result = disambiguate_c(data, languages) + result = disambiguate_c(data) end if languages.all? { |l| ["Perl", "Prolog"].include?(l) } - result = disambiguate_pl(data, languages) + result = disambiguate_pl(data) end if languages.all? { |l| ["ECL", "Prolog"].include?(l) } - result = disambiguate_ecl(data, languages) + result = disambiguate_ecl(data) end if languages.all? { |l| ["IDL", "Prolog"].include?(l) } - result = disambiguate_pro(data, languages) + result = disambiguate_pro(data) end if languages.all? { |l| ["Common Lisp", "OpenCL"].include?(l) } - result = disambiguate_cl(data, languages) + result = disambiguate_cl(data) + end + if languages.all? { |l| ["Hack", "PHP"].include?(l) } + result = disambiguate_hack(data) + end + if languages.all? { |l| ["Scala", "SuperCollider"].include?(l) } + result = disambiguate_sc(data) + end + if languages.all? { |l| ["AsciiDoc", "AGS Script"].include?(l) } + result = disambiguate_asc(data) + end + if languages.all? { |l| ["FORTRAN", "Forth"].include?(l) } + result = disambiguate_f(data) end return result end @@ -36,33 +50,38 @@ module Linguist # We want to shortcut look for Objective-C _and_ now C++ too! # # Returns an array of Languages or [] - def self.disambiguate_c(data, languages) + def self.disambiguate_c(data) matches = [] if (/@(interface|class|protocol|property|end|synchronised|selector|implementation)\b/.match(data)) matches << Language["Objective-C"] - end - if (/^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/.match(data) || + elsif (/^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/.match(data) || /^\s*template\s*")) matches << Language["XML"] @@ -82,20 +101,60 @@ module Linguist matches end - def self.disambiguate_cl(data, languages) + def self.disambiguate_cl(data) matches = [] - matches << Language["Common Lisp"] if data.include?("(defun ") - matches << Language["OpenCL"] if /\/\* |\/\/ |^\}/.match(data) + if data.include?("(defun ") + matches << Language["Common Lisp"] + elsif /\/\* |\/\/ |^\}/.match(data) + matches << Language["OpenCL"] + end matches end - def self.disambiguate_r(data, languages) + def self.disambiguate_r(data) matches = [] matches << Language["Rebol"] if /\bRebol\b/i.match(data) matches << Language["R"] if data.include?("<-") matches end + def self.disambiguate_hack(data) + matches = [] + if data.include?(" 1 data = blob.data possible_language_names = possible_languages.map(&:name) + heuristic_languages = Heuristics.find_by_heuristics(data, possible_language_names) + + if heuristic_languages.size > 1 + possible_language_names = heuristic_languages.map(&:name) + end - # Don't bother with binary contents or an empty file - if data.nil? || data == "" - nil # Check if there's a shebang line and use that as authoritative - elsif (result = find_by_shebang(data)) && !result.empty? + if (result = find_by_shebang(data)) && !result.empty? result.first # No shebang. Still more work to do. Try to find it with our heuristics. - elsif (determined = Heuristics.find_by_heuristics(data, possible_language_names)) && !determined.empty? - determined.first + elsif heuristic_languages.size == 1 + heuristic_languages.first # Lastly, fall back to the probabilistic classifier. elsif classified = Classifier.classify(Samples.cache, data, possible_language_names).first # Return the actual Language object based of the string language name (i.e., first element of `#classify`) @@ -164,7 +161,7 @@ module Linguist # # Returns the Language or nil if none was found. def self.find_by_name(name) - @name_index[name] + name && @name_index[name.downcase] end # Public: Look up Language by one of its aliases. @@ -178,7 +175,7 @@ module Linguist # # Returns the Lexer or nil if none was found. def self.find_by_alias(name) - @alias_index[name] + name && @alias_index[name.downcase] end # Public: Look up Languages by filename. @@ -194,9 +191,25 @@ module Linguist def self.find_by_filename(filename) basename = File.basename(filename) extname = FileBlob.new(filename).extension - langs = @filename_index[basename] + - @extension_index[extname] - langs.compact.uniq + (@filename_index[basename] + find_by_extension(extname)).compact.uniq + end + + # Public: Look up Languages by file extension. + # + # extname - The extension String. + # + # Examples + # + # Language.find_by_extension('.rb') + # # => [#] + # + # Language.find_by_extension('rb') + # # => [#] + # + # Returns all matching Languages or [] if none were found. + def self.find_by_extension(extname) + extname = ".#{extname}" unless extname.start_with?(".") + @extension_index[extname] end # Public: Look up Languages by shebang line. @@ -227,7 +240,7 @@ module Linguist # # Returns the Language or nil if none was found. def self.[](name) - @index[name] + name && @index[name.downcase] end # Public: A List of popular languages @@ -286,10 +299,7 @@ module Linguist # Set aliases @aliases = [default_alias_name] + (attributes[:aliases] || []) - # Lookup Lexer object - @lexer = Pygments::Lexer.find_by_name(attributes[:lexer] || name) || - raise(ArgumentError, "#{@name} is missing lexer") - + # Load the TextMate scope name or try to guess one @tm_scope = attributes[:tm_scope] || begin context = case @type when :data, :markup, :prose @@ -421,11 +431,6 @@ module Linguist # Returns the extensions Array attr_reader :filenames - # Public: Return all possible extensions for language - def all_extensions - (extensions + [primary_extension]).uniq - end - # Deprecated: Get primary extension # # Defaults to the first extension but can be overridden @@ -533,8 +538,8 @@ module Linguist languages_yml = File.expand_path("../languages.yml", __FILE__) languages_json = File.expand_path("../languages.json", __FILE__) - if File.exist?(languages_json) && defined?(JSON) - languages = JSON.load(File.read(languages_json)) + if File.exist?(languages_json) && defined?(Yajl) + languages = Yajl.load(File.read(languages_json)) else languages = YAML.load_file(languages_yml) end @@ -583,9 +588,9 @@ module Linguist :ace_mode => options['ace_mode'], :wrap => options['wrap'], :group_name => options['group'], - :searchable => options.key?('searchable') ? options['searchable'] : true, + :searchable => options.fetch('searchable', true), :search_term => options['search_term'], - :extensions => [options['extensions'].first] + options['extensions'][1..-1].sort, + :extensions => Array(options['extensions']), :interpreters => options['interpreters'].sort, :filenames => options['filenames'], :popular => popular.include?(name) diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 22ecfc6b..71caf5ee 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -1,10 +1,6 @@ # Defines all Languages known to GitHub. # -# All languages have an associated lexer for syntax highlighting. It -# defaults to name.downcase, which covers most cases. -# # type - Either data, programming, markup, prose, or nil -# lexer - An explicit lexer String (defaults to name) # aliases - An Array of additional aliases (implicitly # includes name.downcase) # ace_mode - A String name of Ace Mode (if available) @@ -16,6 +12,10 @@ # search_term - Deprecated: Some languages maybe indexed under a # different alias. Avoid defining new exceptions. # color - CSS hex color to represent the language. +# tm_scope - The TextMate scope that represents this programming +# language. This should match one of the scopes listed in +# the grammars.yml file. Use "none" if there is no grammar +# for this language. # # Any additions or modifications (even trivial) should have corresponding # test change in `test/test_blob.rb`. @@ -24,13 +24,11 @@ ABAP: type: programming - lexer: ABAP extensions: - .abap AGS Script: type: programming - lexer: C++ color: "#B9D9FF" aliases: - ags @@ -42,7 +40,6 @@ AGS Script: ANTLR: type: programming color: "#9DC3FF" - lexer: ANTLR extensions: - .g4 @@ -52,11 +49,11 @@ APL: extensions: - .apl - .dyalog + tm_scope: none ASP: type: programming color: "#6a40fd" - lexer: aspx-vb search_term: aspx-vb aliases: - aspx @@ -73,7 +70,6 @@ ASP: ATS: type: programming color: "#1ac620" - lexer: OCaml aliases: - ats2 extensions: @@ -85,11 +81,12 @@ ATS: ActionScript: type: programming - lexer: ActionScript 3 tm_scope: source.actionscript.3 color: "#e3491a" search_term: as3 aliases: + - actionscript 3 + - actionscript3 - as3 extensions: - .as @@ -99,7 +96,10 @@ Ada: color: "#02f88c" extensions: - .adb + - .ada - .ads + aliases: + - ada95ada2005 Agda: type: programming @@ -109,22 +109,29 @@ Agda: Alloy: type: programming # 'modeling' would be more appropiate - lexer: Alloy color: "#cc5c24" extensions: - .als +Ant Build System: + type: data + tm_scope: text.xml.ant + filenames: + - ant.xml + - build.xml + ApacheConf: type: markup aliases: + - aconf - apache extensions: - .apacheconf + - .conf tm_scope: source.apache-config Apex: type: programming - lexer: Java extensions: - .cls tm_scope: source.java @@ -142,44 +149,43 @@ AppleScript: Arc: type: programming color: "#ca2afe" - lexer: Text only extensions: - .arc + tm_scope: none Arduino: type: programming color: "#bd79d1" - lexer: C++ extensions: - .ino tm_scope: source.c++ AsciiDoc: type: prose - lexer: Text only ace_mode: asciidoc wrap: true extensions: - .asciidoc - .adoc - .asc + tm_scope: none AspectJ: type: programming - lexer: AspectJ color: "#1957b0" extensions: - .aj + tm_scope: none Assembly: type: programming - lexer: NASM color: "#a67219" search_term: nasm aliases: - nasm extensions: - .asm + - .ASM - .a51 tm_scope: source.asm.x86 @@ -187,15 +193,17 @@ Augeas: type: programming extensions: - .aug + tm_scope: none AutoHotkey: type: programming - lexer: autohotkey color: "#6594b9" aliases: - ahk extensions: - .ahk + - .ahkl + tm_scope: none AutoIt: type: programming @@ -210,7 +218,6 @@ AutoIt: Awk: type: programming - lexer: Awk extensions: - .awk - .auk @@ -229,6 +236,9 @@ Batchfile: search_term: bat aliases: - bat + - batch + - dosbatch + - winbatch extensions: - .bat - .cmd @@ -238,11 +248,19 @@ Befunge: extensions: - .befunge +Bison: + type: programming + tm_scope: source.bison + extensions: + - .y + BlitzBasic: type: programming aliases: - - blitzplus + - b3d - blitz3d + - blitzplus + - bplus extensions: - .bb - .decls @@ -253,10 +271,11 @@ BlitzMax: color: "#cd6400" extensions: - .bmx + aliases: + - bmax Bluespec: type: programming - lexer: verilog extensions: - .bsv tm_scope: source.verilog @@ -275,9 +294,9 @@ Brainfuck: Brightscript: type: programming - lexer: Text only extensions: - .brs + tm_scope: none Bro: type: programming @@ -293,6 +312,7 @@ C: - .H - .cats - .h + - .idc - .w C#: @@ -326,20 +346,18 @@ C++: - .hpp - .hxx - .inl + - .ipp - .tcc - .tpp - - .ipp C-ObjDump: type: data - lexer: c-objdump extensions: - .c-objdump tm_scope: objdump.x86asm C2hs Haskell: type: programming - lexer: Haskell group: Haskell aliases: - c2hs @@ -349,9 +367,9 @@ C2hs Haskell: CLIPS: type: programming - lexer: Text only extensions: - .clp + tm_scope: none CMake: extensions: @@ -364,6 +382,8 @@ COBOL: type: programming extensions: - .cob + - .COB + - .CPY - .cbl - .ccp - .cobol @@ -375,9 +395,14 @@ CSS: extensions: - .css +Cap'n Proto: + type: programming + tm_scope: source.capnp + extensions: + - .capnp + Ceylon: type: programming - lexer: Ceylon extensions: - .ceylon @@ -390,7 +415,6 @@ Chapel: - .chpl ChucK: - lexer: Java extensions: - .ck tm_scope: source.java @@ -399,17 +423,16 @@ Cirru: type: programming color: "#aaaaff" ace_mode: cirru - lexer: Cirru extensions: - .cirru Clean: type: programming color: "#3a81ad" - lexer: Text only extensions: - .icl - .dcl + tm_scope: none Clojure: type: programming @@ -438,6 +461,7 @@ CoffeeScript: extensions: - .coffee - ._coffee + - .cjsx - .cson - .iced filenames: @@ -448,21 +472,21 @@ CoffeeScript: ColdFusion: type: programming group: ColdFusion - lexer: Coldfusion HTML ace_mode: coldfusion color: "#ed2cd6" search_term: cfm aliases: - cfm - cfml + - coldfusion html extensions: - .cfm + - .cfml tm_scope: text.html.cfm ColdFusion CFC: type: programming group: ColdFusion - lexer: Coldfusion CFC ace_mode: coldfusion color: "#ed2cd6" search_term: cfc @@ -494,12 +518,14 @@ Common Lisp: Component Pascal: type: programming - lexer: Delphi color: "#b0ce4e" extensions: - .cp - .cps tm_scope: source.pascal + aliases: + - delphi + - objectpascal Coq: type: programming @@ -509,37 +535,39 @@ Coq: Cpp-ObjDump: type: data - lexer: cpp-objdump extensions: - .cppobjdump + - .c++-objdump - .c++objdump + - .cpp-objdump - .cxx-objdump tm_scope: objdump.x86asm + aliases: + - c++-objdumb Creole: type: prose - lexer: Text only wrap: true extensions: - .creole + tm_scope: none Crystal: type: programming - lexer: Ruby extensions: - .cr ace_mode: ruby tm_scope: source.ruby Cucumber: - lexer: Gherkin extensions: - .feature tm_scope: text.gherkin.feature + aliases: + - gherkin Cuda: type: programming - lexer: CUDA extensions: - .cu - .cuh @@ -547,7 +575,6 @@ Cuda: Cycript: type: programming - lexer: JavaScript extensions: - .cy tm_scope: source.js @@ -559,6 +586,8 @@ Cython: - .pyx - .pxd - .pxi + aliases: + - pyrex D: type: programming @@ -569,7 +598,6 @@ D: D-ObjDump: type: data - lexer: d-objdump extensions: - .d-objdump tm_scope: objdump.x86asm @@ -577,20 +605,12 @@ D-ObjDump: DM: type: programming color: "#075ff1" - lexer: C++ extensions: - .dm aliases: - byond tm_scope: source.c++ -DOT: - type: data - lexer: Text only - extensions: - - .dot - - .gv - Darcs Patch: search_term: dpatch aliases: @@ -598,6 +618,7 @@ Darcs Patch: extensions: - .darcspatch - .dpatch + tm_scope: none Dart: type: programming @@ -609,57 +630,65 @@ Diff: extensions: - .diff - .patch + aliases: + - udiff + +Dockerfile: + type: data + tm_scope: source.dockerfile + extensions: + - .dockerfile + filenames: + - Dockerfile Dogescript: type: programming - lexer: Text only color: "#cca760" extensions: - .djs + tm_scope: none Dylan: type: programming color: "#3ebc27" extensions: - .dylan + - .dyl - .intr - .lid E: type: programming color: "#ccce35" - lexer: Text only extensions: - .E - -Ecere Projects: - type: data - group: JavaScript - lexer: JSON - extensions: - - .epj - tm_scope: source.json + tm_scope: none ECL: type: programming color: "#8a1267" - lexer: ECL extensions: - .ecl - .eclxml + tm_scope: none Eagle: type: markup color: "#3994bc" - lexer: XML extensions: - .sch - .brd tm_scope: text.xml +Ecere Projects: + type: data + group: JavaScript + extensions: + - .epj + tm_scope: source.json + Eiffel: type: programming - lexer: Eiffel color: "#946d57" extensions: - .e @@ -673,14 +702,12 @@ Elixir: Elm: type: programming - lexer: Haskell extensions: - .elm tm_scope: source.haskell Emacs Lisp: type: programming - lexer: Common Lisp tm_scope: source.lisp color: "#c065db" aliases: @@ -695,7 +722,6 @@ Emacs Lisp: EmberScript: type: programming color: "#f64e3e" - lexer: CoffeeScript extensions: - .em - .emberscript @@ -706,12 +732,12 @@ Erlang: color: "#0faf8d" extensions: - .erl + - .es - .escript - .hrl F#: type: programming - lexer: FSharp color: "#b845fc" search_term: fsharp aliases: @@ -725,14 +751,13 @@ F#: FLUX: type: programming color: "#33CCFF" - lexer: Text only extensions: - .fx - .flux + tm_scope: none FORTRAN: type: programming - lexer: Fortran color: "#4d41b1" extensions: - .f90 @@ -751,6 +776,7 @@ FORTRAN: - .f95 - .for - .fpp + tm_scope: source.fortran.modern Factor: type: programming @@ -758,8 +784,8 @@ Factor: extensions: - .factor filenames: - - .factor-rc - .factor-boot-rc + - .factor-rc Fancy: type: programming @@ -780,51 +806,44 @@ Fantom: Forth: type: programming color: "#341708" - lexer: Text only extensions: - .fth - .4th + - .F + - .f + - .for - .forth - .frt Frege: type: programming color: "#00cafe" - lexer: Haskell extensions: - .fr tm_scope: source.haskell G-code: type: data - lexer: Text only extensions: - .g - .gco - .gcode - -Game Maker Language: - type: programming - color: "#8ad353" - lexer: JavaScript - extensions: - - .gml - tm_scope: source.js + tm_scope: none GAMS: type: programming - lexer: Text only extensions: - .gms + tm_scope: none GAP: type: programming - lexer: Text only extensions: - .g - .gap - .gd - .gi + tm_scope: none GAS: type: programming @@ -832,12 +851,13 @@ GAS: extensions: - .s - .S + tm_scope: source.asm.x86 GDScript: type: programming - lexer: Text only extensions: - .gd + tm_scope: none GLSL: group: C @@ -848,6 +868,7 @@ GLSL: - .frag - .frg - .fshader + - .geo - .geom - .glslv - .gshader @@ -856,21 +877,29 @@ GLSL: - .vrx - .vshader +Game Maker Language: + type: programming + color: "#8ad353" + extensions: + - .gml + tm_scope: source.js + Genshi: extensions: - .kid tm_scope: text.xml.genshi + aliases: + - xml+genshi + - xml+kid Gentoo Ebuild: group: Shell - lexer: Bash extensions: - .ebuild tm_scope: source.shell Gentoo Eclass: group: Shell - lexer: Bash extensions: - .eclass tm_scope: source.shell @@ -888,7 +917,6 @@ Gettext Catalog: Glyph: type: programming color: "#e4cc98" - lexer: Tcl extensions: - .glf tm_scope: source.tcl @@ -896,7 +924,6 @@ Glyph: Gnuplot: type: programming color: "#f0a9f0" - lexer: Gnuplot extensions: - .gp - .gnu @@ -910,6 +937,13 @@ Go: extensions: - .go +Golo: + type: programming + color: "#f6a51f" + extensions: + - .golo + tm_scope: none + Gosu: type: programming color: "#82937f" @@ -922,13 +956,12 @@ Gosu: Grace: type: programming - lexer: Text only extensions: - .grace + tm_scope: none Grammatical Framework: type: programming - lexer: Haskell aliases: - gf wrap: false @@ -940,9 +973,17 @@ Grammatical Framework: Graph Modeling Language: type: data - lexer: Text only extensions: - .gml + tm_scope: none + +Graphviz (DOT): + type: data + tm_scope: source.dot + extensions: + - .dot + - .DOT + - .gv Groff: extensions: @@ -955,6 +996,8 @@ Groff: - '.6' - '.7' tm_scope: text.groff + aliases: + - nroff Groovy: type: programming @@ -970,9 +1013,9 @@ Groovy: Groovy Server Pages: group: Groovy - lexer: Java Server Page aliases: - gsp + - java server page extensions: - .gsp tm_scope: text.html.jsp @@ -987,22 +1030,25 @@ HTML: - .html - .htm - .st + - .xht - .xhtml HTML+Django: type: markup tm_scope: text.html.django group: HTML - lexer: HTML+Django/Jinja extensions: - .mustache - .jinja + aliases: + - html+django/jinja + - html+jinja + - htmldjango HTML+ERB: type: markup tm_scope: text.html.erb group: HTML - lexer: RHTML aliases: - erb extensions: @@ -1020,6 +1066,15 @@ HTTP: type: data extensions: - .http + tm_scope: none + +Hack: + type: programming + ace_mode: php + extensions: + - .hh + - .php + tm_scope: none Haml: group: HTML @@ -1030,7 +1085,6 @@ Haml: Handlebars: type: markup - lexer: Handlebars aliases: - hbs extensions: @@ -1040,10 +1094,10 @@ Handlebars: Harbour: type: programming - lexer: Text only color: "#0e60e3" extensions: - .hb + tm_scope: none Haskell: type: programming @@ -1063,15 +1117,16 @@ Haxe: Hy: type: programming - lexer: Hy ace_mode: clojure color: "#7891b1" extensions: - .hy + aliases: + - hylang + tm_scope: none IDL: type: programming - lexer: IDL color: "#e3592c" extensions: - .pro @@ -1079,52 +1134,55 @@ IDL: IGOR Pro: type: programming - lexer: Igor extensions: - .ipf + aliases: + - igor + - igorpro + tm_scope: none INI: type: data extensions: - .ini + - .cfg - .prefs - .properties tm_scope: source.ini + aliases: + - dosini -Inno Setup: +IRC log: + search_term: irc + aliases: + - irc + - irc logs extensions: - - .iss - lexer: Text only + - .irclog + - .weechatlog + tm_scope: none Idris: type: programming - lexer: Idris extensions: - .idr - .lidr Inform 7: type: programming - lexer: Inform 7 wrap: true extensions: - .ni - .i7x - tm_scope: source.inform + tm_scope: source.Inform7 + aliases: + - i7 + - inform7 Inno Setup: extensions: - .iss - lexer: Text only - -IRC log: - lexer: IRC logs - search_term: irc - aliases: - - irc - extensions: - - .irclog - - .weechatlog + tm_scope: none Io: type: programming @@ -1140,16 +1198,16 @@ Ioke: Isabelle: type: programming - lexer: Text only color: "#fdcd00" extensions: - .thy + tm_scope: none J: type: programming - lexer: Text only extensions: - .ijs + tm_scope: none JSON: type: data @@ -1173,7 +1231,6 @@ JSON: JSON5: type: data - lexer: JavaScript extensions: - .json5 tm_scope: source.js @@ -1182,7 +1239,6 @@ JSONLD: type: data group: JavaScript ace_mode: json - lexer: JavaScript extensions: - .jsonld tm_scope: source.js @@ -1190,7 +1246,6 @@ JSONLD: JSONiq: type: programming ace_mode: jsoniq - lexer: XQuery extensions: - .jq tm_scope: source.xquery @@ -1211,7 +1266,6 @@ Java: Java Server Pages: group: Java - lexer: Java Server Page search_term: jsp aliases: - jsp @@ -1257,15 +1311,14 @@ Julia: color: "#a270ba" KRL: - lexer: Text only type: programming color: "#f5c800" extensions: - .krl + tm_scope: none Kit: type: markup - lexer: HTML ace_mode: html extensions: - .kit @@ -1284,7 +1337,6 @@ LFE: extensions: - .lfe color: "#004200" - lexer: Common Lisp group: Erlang tm_scope: source.lisp @@ -1294,14 +1346,13 @@ LLVM: LOLCODE: type: programming - lexer: Text only extensions: - .lol color: "#cc9900" + tm_scope: none LSL: type: programming - lexer: LSL ace_mode: lsl extensions: - .lsl @@ -1311,26 +1362,27 @@ LSL: LabVIEW: type: programming - lexer: Text only extensions: - .lvproj + tm_scope: none Lasso: type: programming - lexer: Lasso color: "#2584c3" extensions: - .lasso - .las + - .lasso8 - .lasso9 - .ldml tm_scope: file.lasso + aliases: + - lassoscript Latte: type: markup color: "#A8FF97" group: HTML - lexer: Smarty extensions: - .latte tm_scope: source.smarty @@ -1338,34 +1390,32 @@ Latte: Less: type: markup group: CSS - lexer: CSS extensions: - .less - tm_scope: source.css + tm_scope: source.css.less LilyPond: - lexer: Text only extensions: - .ly - .ily Liquid: type: markup - lexer: Text only extensions: - .liquid + tm_scope: none Literate Agda: type: programming group: Agda extensions: - .lagda + tm_scope: none Literate CoffeeScript: type: programming tm_scope: source.litcoffee group: CoffeeScript - lexer: Text only ace_mode: markdown wrap: true search_term: litcoffee @@ -1379,6 +1429,7 @@ Literate Haskell: group: Haskell search_term: lhs aliases: + - lhaskell - lhs extensions: - .lhs @@ -1389,6 +1440,7 @@ LiveScript: ace_mode: ls color: "#499886" aliases: + - live-script - ls extensions: - .ls @@ -1400,6 +1452,8 @@ Logos: type: programming extensions: - .xm + - .x + - .xi Logtalk: type: programming @@ -1409,7 +1463,6 @@ Logtalk: LookML: type: programming - lexer: YAML ace_mode: yaml color: "#652B81" extensions: @@ -1426,12 +1479,12 @@ Lua: - .nse - .pd_lua - .rbxs + - .wlua interpreters: - lua M: type: programming - lexer: Common Lisp aliases: - mumps extensions: @@ -1441,22 +1494,24 @@ M: MTML: type: markup - lexer: HTML color: "#0095d9" extensions: - .mtml tm_scope: text.html.basic Makefile: + type: programming aliases: + - bsdmake - make + - mf extensions: - .mak - .mk filenames: - - makefile - - Makefile - GNUmakefile + - Makefile + - makefile interpreters: - make @@ -1468,7 +1523,6 @@ Mako: Markdown: type: prose - lexer: Text only ace_mode: markdown wrap: true extensions: @@ -1482,7 +1536,6 @@ Markdown: Mask: type: markup - lexer: SCSS color: "#f97732" ace_mode: scss extensions: @@ -1493,9 +1546,13 @@ Mathematica: type: programming extensions: - .mathematica + - .cdf - .m + - .ma - .nb - lexer: Mathematica + - .nbp + aliases: + - mma Matlab: type: programming @@ -1504,10 +1561,15 @@ Matlab: - .matlab - .m +Maven POM: + type: data + tm_scope: text.xml.pom + filenames: + - pom.xml + Max: type: programming color: "#ce279c" - lexer: JSON aliases: - max/msp - maxmsp @@ -1522,15 +1584,14 @@ Max: MediaWiki: type: prose - lexer: Text only wrap: true extensions: - .mediawiki + tm_scope: none Mercury: type: programming color: "#abcdef" - lexer: Prolog ace_mode: prolog extensions: - .m @@ -1541,10 +1602,10 @@ MiniD: # Legacy searchable: false extensions: - .minid # Dummy extension + tm_scope: none Mirah: type: programming - lexer: Ruby search_term: mirah color: "#c7a938" extensions: @@ -1556,15 +1617,14 @@ Mirah: Monkey: type: programming - lexer: Monkey extensions: - .monkey Moocode: type: programming - lexer: MOOCode extensions: - .moo + tm_scope: none MoonScript: type: programming @@ -1576,6 +1636,7 @@ MoonScript: Myghty: extensions: - .myt + tm_scope: none NSIS: extensions: @@ -1590,7 +1651,6 @@ Nemerle: NetLogo: type: programming - lexer: Common Lisp color: "#ff2b2b" extensions: - .nlogo @@ -1598,10 +1658,11 @@ NetLogo: Nginx: type: markup - lexer: Nginx configuration file extensions: - .nginxconf tm_scope: source.nginx + aliases: + - nginx configuration file Nimrod: type: programming @@ -1610,22 +1671,29 @@ Nimrod: - .nim - .nimrod +Ninja: + type: data + tm_scope: source.ninja + extensions: + - .ninja + Nit: type: programming - lexer: Text only color: "#0d8921" extensions: - .nit + tm_scope: none Nix: type: programming - lexer: Nix extensions: - .nix + aliases: + - nixos + tm_scope: none Nu: type: programming - lexer: Scheme color: "#c9df40" aliases: - nush @@ -1641,6 +1709,7 @@ NumPy: - .numpy - .numpyw - .numsc + tm_scope: none OCaml: type: programming @@ -1657,7 +1726,6 @@ OCaml: ObjDump: type: data - lexer: objdump extensions: - .objdump tm_scope: objdump.x86asm @@ -1669,6 +1737,7 @@ Objective-C: aliases: - obj-c - objc + - objectivec extensions: - .m - .h @@ -1680,6 +1749,7 @@ Objective-C++: aliases: - obj-c++ - objc++ + - objectivec++ extensions: - .mm @@ -1688,6 +1758,8 @@ Objective-J: color: "#ff0c5a" aliases: - obj-j + - objectivej + - objj extensions: - .j - .sj @@ -1698,7 +1770,7 @@ Omgrofl: extensions: - .omgrofl color: "#cabbff" - lexer: Text only + tm_scope: none Opa: type: programming @@ -1708,14 +1780,13 @@ Opa: Opal: type: programming color: "#f7ede0" - lexer: Text only extensions: - .opal + tm_scope: none OpenCL: type: programming group: C - lexer: C extensions: - .cl - .opencl @@ -1734,35 +1805,34 @@ OpenEdge ABL: OpenSCAD: type: programming - lexer: Text only extensions: - .scad + tm_scope: none Org: type: prose - lexer: Text only wrap: true extensions: - .org + tm_scope: none Ox: type: programming - lexer: Text only extensions: - .ox - .oxh - .oxo + tm_scope: none Oxygene: type: programming - lexer: Text only color: "#5a63a3" extensions: - .oxygene + tm_scope: none PAWN: type: programming - lexer: C++ color: "#dbb284" extensions: - .pwn @@ -1787,42 +1857,50 @@ PHP: - Phakefile interpreters: - php + aliases: + - inc Pan: type: programming - lexer: Pan color: '#cc0000' extensions: - .pan + tm_scope: none + +Papyrus: + type: programming + color: "#6600cc" + extensions: + - .psc + tm_scope: none Parrot: type: programming color: "#f3ca0a" - lexer: Text only extensions: - .parrot # Dummy extension + tm_scope: none + +Parrot Assembly: + group: Parrot + type: programming + aliases: + - pasm + extensions: + - .pasm + tm_scope: none Parrot Internal Representation: group: Parrot + tm_scope: source.parrot.pir type: programming - lexer: Text only aliases: - pir extensions: - .pir -Parrot Assembly: - group: Parrot - type: programming - lexer: Text only - aliases: - - pasm - extensions: - - .pasm - Pascal: type: programming - lexer: Delphi color: "#b0ce4e" extensions: - .pas @@ -1862,36 +1940,36 @@ Perl6: - .p6m - .pl6 - .pm6 + tm_scope: none PigLatin: type: programming color: "#fcd7de" - lexer: Text only extensions: - .pig + tm_scope: none Pike: type: programming color: "#066ab2" - lexer: Pike extensions: - .pike - .pmod Pod: type: prose - lexer: Text only ace_mode: perl wrap: true extensions: - .pod + tm_scope: none PogoScript: type: programming color: "#d80074" - lexer: Text only extensions: - .pogo + tm_scope: none PostScript: type: markup @@ -1899,6 +1977,8 @@ PostScript: - .ps - .eps tm_scope: source.postscript + aliases: + - postscr PowerShell: type: programming @@ -1912,14 +1992,12 @@ PowerShell: Processing: type: programming - lexer: Java color: "#2779ab" extensions: - .pde Prolog: type: programming - lexer: Logtalk color: "#74283c" extensions: - .pl @@ -1929,10 +2007,10 @@ Prolog: Propeller Spin: type: programming - lexer: Text only color: "#2b446d" extensions: - .spin + tm_scope: none Protocol Buffer: type: markup @@ -1954,14 +2032,13 @@ Puppet: Pure Data: type: programming color: "#91de79" - lexer: Text only extensions: - .pd + tm_scope: none PureScript: type: programming color: "#bcdc53" - lexer: Haskell extensions: - .purs tm_scope: source.haskell @@ -1980,22 +2057,24 @@ Python: - .pyp - .pyt - .pyw + - .tac - .wsgi - .xpy filenames: - - wscript - - SConstruct + - BUILD - SConscript + - SConstruct + - wscript interpreters: - python Python traceback: type: data group: Python - lexer: Python Traceback searchable: false extensions: - .pytb + tm_scope: text.python.traceback QML: type: markup @@ -2005,7 +2084,6 @@ QML: tm_scope: source.qml QMake: - lexer: Text only extensions: - .pro - .pri @@ -2013,10 +2091,10 @@ QMake: R: type: programming color: "#198ce7" - lexer: S aliases: - R - Rscript + - splus extensions: - .r - .R @@ -2030,7 +2108,6 @@ R: RDoc: type: prose - lexer: Rd ace_mode: rdoc wrap: true extensions: @@ -2039,7 +2116,6 @@ RDoc: REALbasic: type: programming - lexer: VB.net extensions: - .rbbas - .rbfrm @@ -2054,34 +2130,38 @@ RHTML: group: HTML extensions: - .rhtml - tm_scope: text.html.ruby + tm_scope: text.html.erb + aliases: + - html+ruby RMarkdown: type: prose - lexer: Text only wrap: true ace_mode: markdown extensions: - .rmd - .Rmd + tm_scope: none Racket: type: programming - lexer: Racket color: "#ae17ff" extensions: - .rkt - .rktd - .rktl - .scrbl - tm_scope: source.scheme + tm_scope: source.racket Ragel in Ruby Host: type: programming - lexer: Ragel in Ruby Host color: "#ff9c2e" extensions: - .rl + aliases: + - ragel-rb + - ragel-ruby + tm_scope: none Raw token data: search_term: raw @@ -2089,10 +2169,10 @@ Raw token data: - raw extensions: - .raw + tm_scope: none Rebol: type: programming - lexer: REBOL color: "#358a5b" extensions: - .reb @@ -2103,15 +2183,18 @@ Rebol: Red: type: programming - lexer: Text only color: "#ee0000" extensions: - .red - .reds + aliases: + - red/system + tm_scope: none Redcode: extensions: - .cw + tm_scope: none RobotFramework: type: programming @@ -2122,7 +2205,6 @@ RobotFramework: Rouge: type: programming - lexer: Clojure ace_mode: clojure color: "#cc0088" extensions: @@ -2184,9 +2266,9 @@ Rust: SAS: type: programming color: "#1E90FF" - lexer: Text only extensions: - .sas + tm_scope: none SCSS: type: markup @@ -2199,11 +2281,10 @@ SCSS: SQF: type: programming color: "#FFCB1F" - lexer: C++ extensions: - .sqf - .hqf - tm_scope: source.c++ + tm_scope: source.sqf SQL: type: data @@ -2219,14 +2300,12 @@ SQL: STON: type: data group: Smalltalk - lexer: JSON extensions: - .ston tm_scope: source.json Sage: type: programming - lexer: Python group: Python extensions: - .sage @@ -2281,15 +2360,14 @@ Scilab: Self: type: programming color: "#0579aa" - lexer: Text only extensions: - .self + tm_scope: none Shell: type: programming - lexer: Bash search_term: bash - color: "#5861ce" + color: "#89e051" aliases: - sh - bash @@ -2301,27 +2379,29 @@ Shell: - .cgi - .command - .fcgi + - .ksh - .tmux - .zsh interpreters: - bash - sh - zsh - filenames: - - Dockerfile ShellSession: type: programming - lexer: Bash Session extensions: - .sh-session + aliases: + - bash session + - console + tm_scope: text.shell-session Shen: type: programming color: "#120F14" - lexer: Text only extensions: - .shen + tm_scope: none Slash: type: programming @@ -2333,7 +2413,6 @@ Slash: Slim: group: HTML type: markup - lexer: Slim color: "#ff8877" extensions: - .slim @@ -2343,6 +2422,8 @@ Smalltalk: color: "#596706" extensions: - .st + aliases: + - squeak Smarty: extensions: @@ -2359,7 +2440,6 @@ SourcePawn: Squirrel: type: programming - lexer: C++ extensions: - .nut tm_scope: source.c++ @@ -2378,7 +2458,6 @@ Standard ML: Stata: type: programming - lexer: Text only extensions: - .do - .ado @@ -2391,20 +2470,20 @@ Stata: Stylus: type: markup group: CSS - lexer: Text only extensions: - .styl + tm_scope: none SuperCollider: type: programming color: "#46390b" - lexer: Text only extensions: - .scd + - .sc + tm_scope: none Swift: type: programming - lexer: Swift color: "#ffac45" extensions: - .swift @@ -2412,7 +2491,6 @@ Swift: SystemVerilog: type: programming color: "#343761" - lexer: systemverilog extensions: - .sv - .svh @@ -2426,9 +2504,9 @@ TOML: TXL: type: programming - lexer: Text only extensions: - .txl + tm_scope: none Tcl: type: programming @@ -2481,24 +2559,29 @@ Tea: Textile: type: prose - lexer: Text only ace_mode: textile wrap: true extensions: - .textile + tm_scope: none + +Thrift: + type: programming + tm_scope: source.thrift + extensions: + - .thrift Turing: type: programming color: "#45f715" - lexer: Text only extensions: - .t - .tu + tm_scope: none Twig: type: markup group: PHP - lexer: HTML+Django/Jinja extensions: - .twig tm_scope: text.html.twig @@ -2515,7 +2598,6 @@ TypeScript: Unified Parallel C: type: programming group: C - lexer: C ace_mode: c_cpp color: "#755223" extensions: @@ -2525,14 +2607,12 @@ Unified Parallel C: UnrealScript: type: programming color: "#a54c4d" - lexer: Java extensions: - .uc tm_scope: source.java VCL: type: programming - lexer: Perl ace_mode: perl color: "#0298c3" extensions: @@ -2541,7 +2621,6 @@ VCL: VHDL: type: programming - lexer: vhdl color: "#543978" extensions: - .vhdl @@ -2562,7 +2641,6 @@ Vala: Verilog: type: programming - lexer: verilog color: "#848bf3" extensions: - .v @@ -2579,12 +2657,11 @@ VimL: filenames: - .vimrc - _vimrc - - vimrc - gvimrc + - vimrc Visual Basic: type: programming - lexer: VB.net color: "#945db7" extensions: - .vb @@ -2596,18 +2673,19 @@ Visual Basic: - .vbhtml - .vbs tm_scope: source.vbnet + aliases: + - vb.net + - vbnet Volt: - type: programming - lexer: D - color: "#0098db" - extensions: - - .volt - tm_scope: source.d + type: programming + color: "#0098db" + extensions: + - .volt + tm_scope: source.d XC: type: programming - lexer: C extensions: - .xc tm_scope: source.c @@ -2666,6 +2744,7 @@ XML: - .vcxproj - .vxml - .wsdl + - .wsf - .wxi - .wxl - .wxs @@ -2681,11 +2760,15 @@ XML: filenames: - .classpath - .project + - Web.Debug.config + - Web.Release.config + - Web.config + - build.xml.dist + - packages.config - phpunit.xml.dist XProc: type: programming - lexer: XML extensions: - .xpl - .xproc @@ -2702,7 +2785,6 @@ XQuery: - .xqy XS: - lexer: C extensions: - .xs tm_scope: source.c @@ -2718,7 +2800,6 @@ XSLT: Xojo: type: programming - lexer: VB.net extensions: - .xojo_code - .xojo_menu @@ -2746,19 +2827,18 @@ YAML: Zephir: type: programming - lexer: PHP color: "#118f9e" extensions: - .zep - tm_scope: text.html.php + tm_scope: source.php.zephir Zimpl: type: programming - lexer: Text only extensions: - .zimpl - .zmpl - .zpl + tm_scope: none eC: type: programming @@ -2766,10 +2846,10 @@ eC: extensions: - .ec - .eh + tm_scope: none edn: type: data - lexer: Clojure ace_mode: clojure color: "#db5855" extensions: @@ -2779,25 +2859,22 @@ edn: fish: type: programming group: Shell - lexer: Text only extensions: - .fish + tm_scope: none mupad: - lexer: MuPAD extensions: - .mu nesC: type: programming color: "#ffce3b" - lexer: nesC extensions: - .nc ooc: type: programming - lexer: Ooc color: "#b0b77e" extensions: - .ooc @@ -2814,7 +2891,6 @@ reStructuredText: wisp: type: programming - lexer: Clojure ace_mode: clojure color: "#7582D1" extensions: @@ -2823,7 +2899,7 @@ wisp: xBase: type: programming - lexer: Text only color: "#3a4040" extensions: - .prg + tm_scope: none diff --git a/lib/linguist/samples.rb b/lib/linguist/samples.rb index 920bb87e..82c011b1 100644 --- a/lib/linguist/samples.rb +++ b/lib/linguist/samples.rb @@ -1,5 +1,5 @@ begin - require 'json' + require 'yajl' rescue LoadError require 'yaml' end @@ -19,7 +19,7 @@ module Linguist # Hash of serialized samples object def self.cache @cache ||= begin - serializer = defined?(JSON) ? JSON : YAML + serializer = defined?(Yajl) ? Yajl : YAML serializer.load(File.read(PATH)) end end diff --git a/lib/linguist/vendor.yml b/lib/linguist/vendor.yml index 490a910f..31ff7ce7 100644 --- a/lib/linguist/vendor.yml +++ b/lib/linguist/vendor.yml @@ -36,15 +36,16 @@ # Go dependencies - Godeps/_workspace/ -# Bootstrap minified css and js -- (^|/)bootstrap([^.]*)(\.min)?\.(js|css)$ +# Minified JavaScript and CSS +- (\.|-)min\.(js|css)$ + +# Bootstrap css and js +- (^|/)bootstrap([^.]*)\.(js|css)$ # Font Awesome -- font-awesome.min.css - font-awesome.css # Foundation css -- foundation.min.css - foundation.css # Normalize.css @@ -56,7 +57,6 @@ # Animate.css - animate.css -- animate.min.css # Vendored dependencies - third[-_]?party/ @@ -73,12 +73,12 @@ ## Commonly Bundled JavaScript frameworks ## # jQuery -- (^|/)jquery([^.]*)(\.min)?\.js$ -- (^|/)jquery\-\d\.\d+(\.\d+)?(\.min)?\.js$ +- (^|/)jquery([^.]*)\.js$ +- (^|/)jquery\-\d\.\d+(\.\d+)?\.js$ # jQuery UI -- (^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?(\.min)?\.(js|css)$ -- (^|/)jquery\.(ui|effects)\.([^.]*)(\.min)?\.(js|css)$ +- (^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?\.(js|css)$ +- (^|/)jquery\.(ui|effects)\.([^.]*)\.(js|css)$ # Prototype - (^|/)prototype(.*)\.js$ @@ -110,27 +110,32 @@ # MathJax - (^|/)MathJax/ +# Chart.js +- (^|/)Chart\.js$ + +# Codemirror +- (^|/)[Cc]ode[Mm]irror/(lib|mode|theme|addon|keymap) + # SyntaxHighlighter - http://alexgorbatchev.com/ - (^|/)shBrush([^.]*)\.js$ - (^|/)shCore\.js$ - (^|/)shLegacy\.js$ # AngularJS -- (^|/)angular([^.]*)(\.min)?\.js$ +- (^|/)angular([^.]*)\.js$ # D3.js -- (^|\/)d3(\.v\d+)?([^.]*)(\.min)?\.js$ +- (^|\/)d3(\.v\d+)?([^.]*)\.js$ # React -- (^|/)react(-[^.]*)?(\.min)?\.js$ +- (^|/)react(-[^.]*)?\.js$ # Modernizr -- (^|/)modernizr\-\d\.\d+(\.\d+)?(\.min)?\.js$ +- (^|/)modernizr\-\d\.\d+(\.\d+)?\.js$ - (^|/)modernizr\.custom\.\d+\.js$ # Knockout - (^|/)knockout-(\d+\.){3}(debug\.)?js$ -- knockout-min.js ## Python ## @@ -168,8 +173,8 @@ - \.intellisense\.js$ # jQuery validation plugin (MS bundles this with asp.net mvc) -- (^|/)jquery([^.]*)\.validate(\.unobtrusive)?(\.min)?\.js$ -- (^|/)jquery([^.]*)\.unobtrusive\-ajax(\.min)?\.js$ +- (^|/)jquery([^.]*)\.validate(\.unobtrusive)?\.js$ +- (^|/)jquery([^.]*)\.unobtrusive\-ajax\.js$ # Microsoft Ajax - (^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$ @@ -196,7 +201,7 @@ - (^|/)extjs/welcome/ # Html5shiv -- (^|/)html5shiv(\.min)?\.js$ +- (^|/)html5shiv\.js$ # Samples folders - ^[Ss]amples/ @@ -215,8 +220,8 @@ - ^[Tt]est/fixtures/ # PhoneGap/Cordova -- (^|/)cordova([^.]*)(\.min)?\.js$ -- (^|/)cordova\-\d\.\d(\.\d)?(\.min)?\.js$ +- (^|/)cordova([^.]*)\.js$ +- (^|/)cordova\-\d\.\d(\.\d)?\.js$ # Foundation js - foundation(\..*)?\.js$ @@ -236,7 +241,6 @@ # Octicons - octicons.css -- octicons.min.css - sprockets-octicons.scss # Typesafe Activator diff --git a/lib/linguist/version.rb b/lib/linguist/version.rb index f02c0c45..6aa2f696 100644 --- a/lib/linguist/version.rb +++ b/lib/linguist/version.rb @@ -1,3 +1,3 @@ module Linguist - VERSION = "3.4.1" + VERSION = "4.0.3" end diff --git a/package.json b/package.json new file mode 100644 index 00000000..acd7cd9e --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "repository": "https://github.com/github/linguist", + "dependencies": { + "season": "~>3.0" + } +} diff --git a/samples/Ant Build System/filenames/ant.xml b/samples/Ant Build System/filenames/ant.xml new file mode 100644 index 00000000..54e96ddc --- /dev/null +++ b/samples/Ant Build System/filenames/ant.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/Ant Build System/filenames/build.xml b/samples/Ant Build System/filenames/build.xml new file mode 120000 index 00000000..6c7d5cd4 --- /dev/null +++ b/samples/Ant Build System/filenames/build.xml @@ -0,0 +1 @@ +ant.xml \ No newline at end of file diff --git a/samples/C++/bar.hh b/samples/C++/bar.hh new file mode 100644 index 00000000..a87343c2 --- /dev/null +++ b/samples/C++/bar.hh @@ -0,0 +1,10 @@ +class Bar +{ + protected: + + char *name; + + public: + + void hello(); +} diff --git a/samples/CoffeeScript/empty.coffee b/samples/CoffeeScript/empty.coffee deleted file mode 100644 index e69de29b..00000000 diff --git a/samples/CoffeeScript/example.cjsx b/samples/CoffeeScript/example.cjsx new file mode 100644 index 00000000..def9cf2f --- /dev/null +++ b/samples/CoffeeScript/example.cjsx @@ -0,0 +1,40 @@ +###* @cjsx React.DOM ### +define 'myProject.ReactExampleComponent', [ + 'React' + 'myProject.ExampleStore' + 'myProject.ExampleActions' + 'myProject.ReactExampleTable' +], (React, ExampleStore, ExampleActions, ReactExampleTable ) -> + + ReactExampleComponent = React.createClass + mixins: [ListenMixin] + + getInitialState: -> + rows: ExampleStore.getRows() + meta: ExampleStore.getMeta() + + componentWillMount: -> + @listenTo ExampleStore + + componentDidMount: -> + ExampleActions.getExampleData() + + onStoreChange: -> + if this.isMounted() + @setState + rows: ExampleStore.getRows() + meta: ExampleStore.getMeta() + + componentWillUnmount: -> + @stopListening ExampleStore + + render: -> +
+
+ {@state.title} +
+ +
diff --git a/samples/Shell/filenames/Dockerfile b/samples/Dockerfile/filenames/Dockerfile similarity index 100% rename from samples/Shell/filenames/Dockerfile rename to samples/Dockerfile/filenames/Dockerfile diff --git a/samples/FORTRAN/sample1.f b/samples/FORTRAN/sample1.f new file mode 100644 index 00000000..39ba97cb --- /dev/null +++ b/samples/FORTRAN/sample1.f @@ -0,0 +1,25 @@ +c comment +* comment + + program main + + end + + subroutine foo( i, x, b ) + INTEGER i + REAL x + LOGICAL b + + if( i.ne.0 ) then + call bar( -i ) + end if + + return + end + + double complex function baz() + + baz = (0.0d0,0.0d0) + + return + end diff --git a/samples/FORTRAN/sample1.for b/samples/FORTRAN/sample1.for new file mode 100644 index 00000000..39ba97cb --- /dev/null +++ b/samples/FORTRAN/sample1.for @@ -0,0 +1,25 @@ +c comment +* comment + + program main + + end + + subroutine foo( i, x, b ) + INTEGER i + REAL x + LOGICAL b + + if( i.ne.0 ) then + call bar( -i ) + end if + + return + end + + double complex function baz() + + baz = (0.0d0,0.0d0) + + return + end diff --git a/samples/FORTRAN/sample2.f b/samples/FORTRAN/sample2.f new file mode 100644 index 00000000..19538ac7 --- /dev/null +++ b/samples/FORTRAN/sample2.f @@ -0,0 +1,25 @@ + PROGRAM MAIN + + END + +C comment +* comment + + SUBROUTINE foo( i, x, b ) + INTEGER i + REAL x + LOGICAL b + + IF( i.NE.0 ) THEN + CALL bar( -i ) + END IF + + RETURN + END + + DOUBLE COMPLEX FUNCTION baz() + + baz = (0.0d0,0.0d0) + + RETURN + END diff --git a/samples/FORTRAN/sample3.F b/samples/FORTRAN/sample3.F new file mode 100644 index 00000000..39ba97cb --- /dev/null +++ b/samples/FORTRAN/sample3.F @@ -0,0 +1,25 @@ +c comment +* comment + + program main + + end + + subroutine foo( i, x, b ) + INTEGER i + REAL x + LOGICAL b + + if( i.ne.0 ) then + call bar( -i ) + end if + + return + end + + double complex function baz() + + baz = (0.0d0,0.0d0) + + return + end diff --git a/samples/Forth/core.f b/samples/Forth/core.f new file mode 100644 index 00000000..4a13e217 --- /dev/null +++ b/samples/Forth/core.f @@ -0,0 +1,252 @@ +: immediate lastxt @ dup c@ negate swap c! ; + +: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff + +: char \ ( "word" -- char ) + bl-word here 1+ c@ ; + +: ahead here 0 , ; + +: resolve here swap ! ; + +: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ; + +: postpone-nonimmediate [ ' literal , ' compile, ] literal , ; + +: create dovariable_code header, reveal ; + +create postponers + ' postpone-nonimmediate , + ' abort , + ' , , + +: word \ ( char "string" -- caddr ) + drop bl-word here ; + +: postpone \ ( C: "word" -- ) + bl word find 1+ cells postponers + @ execute ; immediate + +: unresolved \ ( C: "word" -- orig ) + postpone postpone postpone ahead ; immediate + +: chars \ ( n1 -- n2 ) + ; + +: else \ ( -- ) ( C: orig1 -- orig2 ) + unresolved branch swap resolve ; immediate + +: if \ ( flag -- ) ( C: -- orig ) + unresolved 0branch ; immediate + +: then \ ( -- ) ( C: orig -- ) + resolve ; immediate + +: [char] \ ( "word" -- ) + char postpone literal ; immediate + +: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ; + +: does> postpone (does>) ; immediate + +: begin \ ( -- ) ( C: -- dest ) + here ; immediate + +: while \ ( x -- ) ( C: dest -- orig dest ) + unresolved 0branch swap ; immediate + +: repeat \ ( -- ) ( C: orig dest -- ) + postpone branch , resolve ; immediate + +: until \ ( x -- ) ( C: dest -- ) + postpone 0branch , ; immediate + +: recurse lastxt @ compile, ; immediate + +: pad \ ( -- addr ) + here 1024 + ; + +: parse \ ( char "string" -- addr n ) + pad >r begin + source? if else 0 0 then + while + r@ c! r> 1+ >r + repeat 2drop pad r> over - ; + +: ( \ ( "string" -- ) + [ char ) ] literal parse 2drop ; immediate + \ TODO: If necessary, refill and keep parsing. + +: string, ( addr n -- ) + here over allot align swap cmove ; + +: (s") ( -- addr n ) ( R: ret1 -- ret2 ) + r> dup @ swap cell+ 2dup + aligned >r swap ; + +create squote 128 allot + +: s" ( "string" -- addr n ) + state @ if + postpone (s") [char] " parse dup , string, + else + [char] " parse >r squote r@ cmove squote r> + then ; immediate + +: (abort") ( ... addr n -- ) ( R: ... -- ) + cr type cr abort ; + +: abort" ( ... x "string" -- ) ( R: ... -- ) + postpone if postpone s" postpone (abort") postpone then ; immediate + +\ ---------------------------------------------------------------------- + +( Core words. ) + +\ TODO: # +\ TODO: #> +\ TODO: #s + +: and ( x y -- x&y ) nand invert ; + +: * 1 2>r 0 swap begin r@ while + r> r> swap 2dup dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +\ TODO: */mod + +: +loop ( -- ) ( C: nest-sys -- ) + postpone (+loop) postpone 0branch , postpone unloop ; immediate + +: space bl emit ; + +: ?.- dup 0 < if [char] - emit negate then ; + +: digit [char] 0 + emit ; + +: (.) base @ /mod ?dup if recurse then digit ; + +: ." ( "string" -- ) postpone s" postpone type ; immediate + +: . ( x -- ) ?.- (.) space ; + +: postpone-number ( caddr -- ) + 0 0 rot count >number dup 0= if + 2drop nip + postpone (literal) postpone (literal) postpone , + postpone literal postpone , + else + ." Undefined: " type cr abort + then ; + +' postpone-number postponers cell+ ! + +: / ( x y -- x/y ) /mod nip ; + +: 0< ( n -- flag ) 0 < ; + +: 1- ( n -- n-1 ) -1 + ; + +: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ; + +: 2* ( n -- 2n ) dup + ; + +\ Kernel: 2/ + +: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ; + +\ Kernel: 2drop +\ Kernel: 2dup + +\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) +\ 3 pick 3 pick ; + +\ TODO: 2swap + +\ TODO: <# + +: abs ( n -- |n| ) + dup 0< if negate then ; + +\ TODO: accept + +: c, ( n -- ) + here c! 1 chars allot ; + +: char+ ( n1 -- n2 ) + 1+ ; + +: constant create , does> @ ; + +: decimal ( -- ) + 10 base ! ; + +: depth ( -- n ) + data_stack 100 cells + 'SP @ - /cell / 2 - ; + +: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys ) + postpone 2>r here ; immediate + +\ TODO: environment? +\ TODO: evaluate +\ TODO: fill +\ TODO: fm/mod ) +\ TODO: hold + +: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 ) + 'RP @ 3 cells + @ ; + +\ TODO: leave + +: loop ( -- ) ( C: nest-sys -- ) + postpone 1 postpone (+loop) + postpone 0branch , + postpone unloop ; immediate + +: lshift begin ?dup while 1- swap dup + swap repeat ; + +: rshift 1 begin over while dup + swap 1- swap repeat nip + 2>r 0 1 begin r@ while + r> r> 2dup swap dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +: max ( x y -- max[x,y] ) + 2dup > if drop else nip then ; + +\ Kernel: min +\ TODO: mod +\ TODO: move + +: (quit) ( R: ... -- ) + return_stack 100 cells + 'RP ! + 0 'source-id ! tib ''source ! #tib ''#source ! + postpone [ + begin + refill + while + interpret state @ 0= if ." ok" cr then + repeat + bye ; + +' (quit) ' quit >body cell+ ! + +\ TODO: s>d +\ TODO: sign +\ TODO: sm/rem + +: spaces ( n -- ) + 0 do space loop ; + +\ TODO: u. + +: signbit ( -- n ) -1 1 rshift invert ; + +: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ; + +: u< ( x y -- flag ) signbit xor swap signbit xor > ; + +\ TODO: um/mod + +: variable ( "word" -- ) + create /cell allot ; + +: ['] \ ( C: "word" -- ) + ' postpone literal ; immediate diff --git a/samples/Forth/core.for b/samples/Forth/core.for new file mode 100644 index 00000000..4a13e217 --- /dev/null +++ b/samples/Forth/core.for @@ -0,0 +1,252 @@ +: immediate lastxt @ dup c@ negate swap c! ; + +: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff + +: char \ ( "word" -- char ) + bl-word here 1+ c@ ; + +: ahead here 0 , ; + +: resolve here swap ! ; + +: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ; + +: postpone-nonimmediate [ ' literal , ' compile, ] literal , ; + +: create dovariable_code header, reveal ; + +create postponers + ' postpone-nonimmediate , + ' abort , + ' , , + +: word \ ( char "string" -- caddr ) + drop bl-word here ; + +: postpone \ ( C: "word" -- ) + bl word find 1+ cells postponers + @ execute ; immediate + +: unresolved \ ( C: "word" -- orig ) + postpone postpone postpone ahead ; immediate + +: chars \ ( n1 -- n2 ) + ; + +: else \ ( -- ) ( C: orig1 -- orig2 ) + unresolved branch swap resolve ; immediate + +: if \ ( flag -- ) ( C: -- orig ) + unresolved 0branch ; immediate + +: then \ ( -- ) ( C: orig -- ) + resolve ; immediate + +: [char] \ ( "word" -- ) + char postpone literal ; immediate + +: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ; + +: does> postpone (does>) ; immediate + +: begin \ ( -- ) ( C: -- dest ) + here ; immediate + +: while \ ( x -- ) ( C: dest -- orig dest ) + unresolved 0branch swap ; immediate + +: repeat \ ( -- ) ( C: orig dest -- ) + postpone branch , resolve ; immediate + +: until \ ( x -- ) ( C: dest -- ) + postpone 0branch , ; immediate + +: recurse lastxt @ compile, ; immediate + +: pad \ ( -- addr ) + here 1024 + ; + +: parse \ ( char "string" -- addr n ) + pad >r begin + source? if else 0 0 then + while + r@ c! r> 1+ >r + repeat 2drop pad r> over - ; + +: ( \ ( "string" -- ) + [ char ) ] literal parse 2drop ; immediate + \ TODO: If necessary, refill and keep parsing. + +: string, ( addr n -- ) + here over allot align swap cmove ; + +: (s") ( -- addr n ) ( R: ret1 -- ret2 ) + r> dup @ swap cell+ 2dup + aligned >r swap ; + +create squote 128 allot + +: s" ( "string" -- addr n ) + state @ if + postpone (s") [char] " parse dup , string, + else + [char] " parse >r squote r@ cmove squote r> + then ; immediate + +: (abort") ( ... addr n -- ) ( R: ... -- ) + cr type cr abort ; + +: abort" ( ... x "string" -- ) ( R: ... -- ) + postpone if postpone s" postpone (abort") postpone then ; immediate + +\ ---------------------------------------------------------------------- + +( Core words. ) + +\ TODO: # +\ TODO: #> +\ TODO: #s + +: and ( x y -- x&y ) nand invert ; + +: * 1 2>r 0 swap begin r@ while + r> r> swap 2dup dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +\ TODO: */mod + +: +loop ( -- ) ( C: nest-sys -- ) + postpone (+loop) postpone 0branch , postpone unloop ; immediate + +: space bl emit ; + +: ?.- dup 0 < if [char] - emit negate then ; + +: digit [char] 0 + emit ; + +: (.) base @ /mod ?dup if recurse then digit ; + +: ." ( "string" -- ) postpone s" postpone type ; immediate + +: . ( x -- ) ?.- (.) space ; + +: postpone-number ( caddr -- ) + 0 0 rot count >number dup 0= if + 2drop nip + postpone (literal) postpone (literal) postpone , + postpone literal postpone , + else + ." Undefined: " type cr abort + then ; + +' postpone-number postponers cell+ ! + +: / ( x y -- x/y ) /mod nip ; + +: 0< ( n -- flag ) 0 < ; + +: 1- ( n -- n-1 ) -1 + ; + +: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ; + +: 2* ( n -- 2n ) dup + ; + +\ Kernel: 2/ + +: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ; + +\ Kernel: 2drop +\ Kernel: 2dup + +\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) +\ 3 pick 3 pick ; + +\ TODO: 2swap + +\ TODO: <# + +: abs ( n -- |n| ) + dup 0< if negate then ; + +\ TODO: accept + +: c, ( n -- ) + here c! 1 chars allot ; + +: char+ ( n1 -- n2 ) + 1+ ; + +: constant create , does> @ ; + +: decimal ( -- ) + 10 base ! ; + +: depth ( -- n ) + data_stack 100 cells + 'SP @ - /cell / 2 - ; + +: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys ) + postpone 2>r here ; immediate + +\ TODO: environment? +\ TODO: evaluate +\ TODO: fill +\ TODO: fm/mod ) +\ TODO: hold + +: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 ) + 'RP @ 3 cells + @ ; + +\ TODO: leave + +: loop ( -- ) ( C: nest-sys -- ) + postpone 1 postpone (+loop) + postpone 0branch , + postpone unloop ; immediate + +: lshift begin ?dup while 1- swap dup + swap repeat ; + +: rshift 1 begin over while dup + swap 1- swap repeat nip + 2>r 0 1 begin r@ while + r> r> 2dup swap dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +: max ( x y -- max[x,y] ) + 2dup > if drop else nip then ; + +\ Kernel: min +\ TODO: mod +\ TODO: move + +: (quit) ( R: ... -- ) + return_stack 100 cells + 'RP ! + 0 'source-id ! tib ''source ! #tib ''#source ! + postpone [ + begin + refill + while + interpret state @ 0= if ." ok" cr then + repeat + bye ; + +' (quit) ' quit >body cell+ ! + +\ TODO: s>d +\ TODO: sign +\ TODO: sm/rem + +: spaces ( n -- ) + 0 do space loop ; + +\ TODO: u. + +: signbit ( -- n ) -1 1 rshift invert ; + +: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ; + +: u< ( x y -- flag ) signbit xor swap signbit xor > ; + +\ TODO: um/mod + +: variable ( "word" -- ) + create /cell allot ; + +: ['] \ ( C: "word" -- ) + ' postpone literal ; immediate diff --git a/samples/Forth/core1.F b/samples/Forth/core1.F new file mode 100644 index 00000000..4a13e217 --- /dev/null +++ b/samples/Forth/core1.F @@ -0,0 +1,252 @@ +: immediate lastxt @ dup c@ negate swap c! ; + +: \ source nip >in ! ; immediate \ Copyright 2004, 2012 Lars Brinkhoff + +: char \ ( "word" -- char ) + bl-word here 1+ c@ ; + +: ahead here 0 , ; + +: resolve here swap ! ; + +: ' bl-word here find 0branch [ ahead ] exit [ resolve ] 0 ; + +: postpone-nonimmediate [ ' literal , ' compile, ] literal , ; + +: create dovariable_code header, reveal ; + +create postponers + ' postpone-nonimmediate , + ' abort , + ' , , + +: word \ ( char "string" -- caddr ) + drop bl-word here ; + +: postpone \ ( C: "word" -- ) + bl word find 1+ cells postponers + @ execute ; immediate + +: unresolved \ ( C: "word" -- orig ) + postpone postpone postpone ahead ; immediate + +: chars \ ( n1 -- n2 ) + ; + +: else \ ( -- ) ( C: orig1 -- orig2 ) + unresolved branch swap resolve ; immediate + +: if \ ( flag -- ) ( C: -- orig ) + unresolved 0branch ; immediate + +: then \ ( -- ) ( C: orig -- ) + resolve ; immediate + +: [char] \ ( "word" -- ) + char postpone literal ; immediate + +: (does>) lastxt @ dodoes_code over >code ! r> swap >does ! ; + +: does> postpone (does>) ; immediate + +: begin \ ( -- ) ( C: -- dest ) + here ; immediate + +: while \ ( x -- ) ( C: dest -- orig dest ) + unresolved 0branch swap ; immediate + +: repeat \ ( -- ) ( C: orig dest -- ) + postpone branch , resolve ; immediate + +: until \ ( x -- ) ( C: dest -- ) + postpone 0branch , ; immediate + +: recurse lastxt @ compile, ; immediate + +: pad \ ( -- addr ) + here 1024 + ; + +: parse \ ( char "string" -- addr n ) + pad >r begin + source? if else 0 0 then + while + r@ c! r> 1+ >r + repeat 2drop pad r> over - ; + +: ( \ ( "string" -- ) + [ char ) ] literal parse 2drop ; immediate + \ TODO: If necessary, refill and keep parsing. + +: string, ( addr n -- ) + here over allot align swap cmove ; + +: (s") ( -- addr n ) ( R: ret1 -- ret2 ) + r> dup @ swap cell+ 2dup + aligned >r swap ; + +create squote 128 allot + +: s" ( "string" -- addr n ) + state @ if + postpone (s") [char] " parse dup , string, + else + [char] " parse >r squote r@ cmove squote r> + then ; immediate + +: (abort") ( ... addr n -- ) ( R: ... -- ) + cr type cr abort ; + +: abort" ( ... x "string" -- ) ( R: ... -- ) + postpone if postpone s" postpone (abort") postpone then ; immediate + +\ ---------------------------------------------------------------------- + +( Core words. ) + +\ TODO: # +\ TODO: #> +\ TODO: #s + +: and ( x y -- x&y ) nand invert ; + +: * 1 2>r 0 swap begin r@ while + r> r> swap 2dup dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +\ TODO: */mod + +: +loop ( -- ) ( C: nest-sys -- ) + postpone (+loop) postpone 0branch , postpone unloop ; immediate + +: space bl emit ; + +: ?.- dup 0 < if [char] - emit negate then ; + +: digit [char] 0 + emit ; + +: (.) base @ /mod ?dup if recurse then digit ; + +: ." ( "string" -- ) postpone s" postpone type ; immediate + +: . ( x -- ) ?.- (.) space ; + +: postpone-number ( caddr -- ) + 0 0 rot count >number dup 0= if + 2drop nip + postpone (literal) postpone (literal) postpone , + postpone literal postpone , + else + ." Undefined: " type cr abort + then ; + +' postpone-number postponers cell+ ! + +: / ( x y -- x/y ) /mod nip ; + +: 0< ( n -- flag ) 0 < ; + +: 1- ( n -- n-1 ) -1 + ; + +: 2! ( x1 x2 addr -- ) swap over ! cell+ ! ; + +: 2* ( n -- 2n ) dup + ; + +\ Kernel: 2/ + +: 2@ ( addr -- x1 x2 ) dup cell+ @ swap @ ; + +\ Kernel: 2drop +\ Kernel: 2dup + +\ TODO: 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) +\ 3 pick 3 pick ; + +\ TODO: 2swap + +\ TODO: <# + +: abs ( n -- |n| ) + dup 0< if negate then ; + +\ TODO: accept + +: c, ( n -- ) + here c! 1 chars allot ; + +: char+ ( n1 -- n2 ) + 1+ ; + +: constant create , does> @ ; + +: decimal ( -- ) + 10 base ! ; + +: depth ( -- n ) + data_stack 100 cells + 'SP @ - /cell / 2 - ; + +: do ( n1 n2 -- ) ( R: -- loop-sys ) ( C: -- do-sys ) + postpone 2>r here ; immediate + +\ TODO: environment? +\ TODO: evaluate +\ TODO: fill +\ TODO: fm/mod ) +\ TODO: hold + +: j ( -- x1 ) ( R: x1 x2 x3 -- x1 x2 x3 ) + 'RP @ 3 cells + @ ; + +\ TODO: leave + +: loop ( -- ) ( C: nest-sys -- ) + postpone 1 postpone (+loop) + postpone 0branch , + postpone unloop ; immediate + +: lshift begin ?dup while 1- swap dup + swap repeat ; + +: rshift 1 begin over while dup + swap 1- swap repeat nip + 2>r 0 1 begin r@ while + r> r> 2dup swap dup + 2>r and if swap over + swap then dup + + repeat r> r> 2drop drop ; + +: max ( x y -- max[x,y] ) + 2dup > if drop else nip then ; + +\ Kernel: min +\ TODO: mod +\ TODO: move + +: (quit) ( R: ... -- ) + return_stack 100 cells + 'RP ! + 0 'source-id ! tib ''source ! #tib ''#source ! + postpone [ + begin + refill + while + interpret state @ 0= if ." ok" cr then + repeat + bye ; + +' (quit) ' quit >body cell+ ! + +\ TODO: s>d +\ TODO: sign +\ TODO: sm/rem + +: spaces ( n -- ) + 0 do space loop ; + +\ TODO: u. + +: signbit ( -- n ) -1 1 rshift invert ; + +: xor ( x y -- x^y ) 2dup nand >r r@ nand swap r> nand nand ; + +: u< ( x y -- flag ) signbit xor swap signbit xor > ; + +\ TODO: um/mod + +: variable ( "word" -- ) + create /cell allot ; + +: ['] \ ( C: "word" -- ) + ' postpone literal ; immediate diff --git a/samples/Golo/adapters.golo b/samples/Golo/adapters.golo new file mode 100755 index 00000000..20c7d031 --- /dev/null +++ b/samples/Golo/adapters.golo @@ -0,0 +1,67 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Adapters + +local function list_sample = |fabric| { + println(">>> list_sample()") + let carbonCopy = list[] + let conf = map[ + ["extends", "java.util.ArrayList"], + ["overrides", map[ + ["*", |super, name, args| { + if name == "add" { + if args: length() == 2 { + carbonCopy: add(args: get(1)) + } else { + carbonCopy: add(args: get(1), args: get(2)) + } + } + return super: invokeWithArguments(args) + } + ]] + ]] + let list = fabric: maker(conf): newInstance() + list: add("bar") + list: add(0, "foo") + list: add("baz") + println(" list: " + list + " " + list: getClass()) + println("carbonCopy: " + carbonCopy + " " + carbonCopy: getClass()) +} + +local function runnable_sample = |fabric| { + println(">>> runnable_sample") + let result = array[1, 2, 3] + let conf = map[ + ["interfaces", ["java.io.Serializable", "java.lang.Runnable"]], + ["implements", map[ + ["run", |this| { + for (var i = 0, i < result: length(), i = i + 1) { + result: set(i, result: get(i) + 10) + } + }] + ]] + ] + let runner = fabric: maker(conf): newInstance() + runner: run() + println(" result: " + result: toString()) + println("serializable? " + (runner oftype java.io.Serializable.class)) + println(" runnable? " + (runner oftype java.lang.Runnable.class)) +} + +function main = |args| { + let fabric = AdapterFabric() + list_sample(fabric) + runnable_sample(fabric) +} diff --git a/samples/Golo/async.golo b/samples/Golo/async.golo new file mode 100755 index 00000000..432f8c94 --- /dev/null +++ b/samples/Golo/async.golo @@ -0,0 +1,84 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.AsyncHelpers + +import gololang.Async +import java.util.concurrent.TimeUnit +import java.util.concurrent.Executors + +local function fib = |n| { + if n <= 1 { + return n + } else { + return fib(n - 1) + fib(n - 2) + } +} + +function main = |args| { + + let executor = newCachedThreadPool() + println("Let's do some useless asynchronous operations...") + + var f = executor: enqueue({ + Thread.sleep(1000_L) + return 666 + }) + f: + onSet(|v| -> println(">>> #slow -> " + v)): + onFail(|e| -> println(">>> #fail -> " + e)) + f: + cancel(true) + + f = executor: enqueue({ + Thread.sleep(1000_L) + return 666 + }) + f: + onSet(|v| -> println(">>> #ok -> " + v)): + onFail(|e| -> println(">>> #wtf? -> " + e)) + + let fib_10 = promise() + let fib_20 = promise() + let fib_30 = promise() + let fib_40 = promise() + + let futures = [ + fib_10: future(), fib_20: future(), + fib_30: future(), fib_40: future() + ] + + executor: submit(-> fib_10: set(fib(10))) + executor: submit(-> fib_20: set(fib(20))) + executor: submit(-> fib_30: set(fib(30))) + executor: submit(-> fib_40: set(fib(40))) + + all(futures): onSet(|results| -> println(">>> Fibs: " + results)) + + let truth = promise() + truth: + future(): + map(|v| -> "truth=" + v): + onSet(|v| -> executor: submit(-> println(">>> (another thread) " + v))): + onSet(|v| -> println(">>> (same thread) " + v)) + executor: submit({ + Thread.sleep(500_L) + truth: set(42) + }) + + Thread.sleep(1000_L) + executor: shutdown() + executor: awaitTermination(2_L, SECONDS()) + println("Bye!") +} diff --git a/samples/Golo/augmentations.golo b/samples/Golo/augmentations.golo new file mode 100755 index 00000000..bed289a4 --- /dev/null +++ b/samples/Golo/augmentations.golo @@ -0,0 +1,37 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Augmentations + +import java.util.LinkedList + +augment java.util.List { + function with = |this, value| { + this: add(value) + return this + } +} + +augment java.util.Collection { + function doToEach = |this, func| { + foreach (element in this) { + func(element) + } + } +} + +function main = |args| { + let list = LinkedList(): with("foo"): with("bar"): with("baz") + list: doToEach(|value| -> println(">>> " + value)) +} diff --git a/samples/Golo/closures.golo b/samples/Golo/closures.golo new file mode 100755 index 00000000..32378017 --- /dev/null +++ b/samples/Golo/closures.golo @@ -0,0 +1,43 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Closures + +local function sayHello = |who| -> "Hello " + who + "!" + +function main = |args| { + let adder = |a, b| -> a + b + println(adder: invokeWithArguments(1, 2)) + println(adder(1, 2)) + + let addToTen = adder: bindTo(10) + println(addToTen: invokeWithArguments(2)) + println(addToTen(2)) + + let adding = |x| -> |y| -> adder(x, y) + let addingTen = adding(10) + println(addingTen(4)) + println(adding(2)(4)) + + println(sayHello("Julien")) + + let list = java.util.LinkedList() + let pump_it = { + list: add("I heard you say") + list: add("Hey!") + list: add("Hey!") + } + pump_it() + println(list) +} diff --git a/samples/Golo/coin-change.golo b/samples/Golo/coin-change.golo new file mode 100755 index 00000000..fe82bb04 --- /dev/null +++ b/samples/Golo/coin-change.golo @@ -0,0 +1,34 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module CoinChange + +import java.util.LinkedList + +function change = |money, coins| -> match { + when money == 0 then 1 + when (money < 0) or (coins: isEmpty()) then 0 + otherwise change(money - coins: head(), coins) + change(money, coins: tail()) +} + +function main = |args| { + let coins = LinkedList(): append(1, 2, 5, 10, 20) + println("Coins: " + coins) + println("0: " + change(0, coins)) + println("1: " + change(1, coins)) + println("2: " + change(2, coins)) + println("10: " + change(10, coins)) + println("12: " + change(12, coins)) + println("6: " + change(6, coins)) +} diff --git a/samples/Golo/collection-literals.golo b/samples/Golo/collection-literals.golo new file mode 100755 index 00000000..ac19b35e --- /dev/null +++ b/samples/Golo/collection-literals.golo @@ -0,0 +1,55 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.CollectionLiterals + +local function play_with_tuples = { + let hello = ["Hello", "world", "!"] + foreach str in hello { + print(str + " ") + } + println("") + + println(hello: get(0) + "-" + hello: get(1) + "-" + hello: get(2)) + + println(hello: join("/")) +} + +local function play_with_literals = { + let data = [ + [1, 2, 3], + tuple[1, 2, 3], + array[1, 2, 3], + set[1, 2, 3, 3, 1], + map[ + ["a", 10], + ["b", 20] + ], + vector[1, 2, 3], + list[1, 2, 3] + ] + + data: each(|element| { + println(element: toString()) + println(" type: " + element: getClass()) + }) +} + +function main = |args| { + println(">>> Literals") + play_with_literals() + println("\n>>> Tuples") + play_with_tuples() +} + diff --git a/samples/Golo/context-decorator.golo b/samples/Golo/context-decorator.golo new file mode 100755 index 00000000..6a3bb889 --- /dev/null +++ b/samples/Golo/context-decorator.golo @@ -0,0 +1,53 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.ContextDecorator + +import gololang.Decorators + +let myContext = defaultContext(): + count(0): + define("entry", |this, args| { + this: count(this: count() + 1) + println("hello:" + this: count()) + return args + }): + define("exit", |this, result| { + require(result >= 3, "wrong value") + println("goobye") + return result + }): + define("catcher", |this, e| { + println("Caught " + e) + throw e + }): + define("finallizer", |this| {println("do some cleanup")}) + + +@withContext(myContext) +function foo = |a, b| { + println("Hard computation") + return a + b +} + +function main = |args| { + println(foo(1,2)) + println("====") + println(withContext(myContext)(|a| -> 2*a)(3)) + println("====") + try { + println(foo(1, 1)) + } catch (e) { } +} + diff --git a/samples/Golo/decorators.golo b/samples/Golo/decorators.golo new file mode 100755 index 00000000..c3acbfc4 --- /dev/null +++ b/samples/Golo/decorators.golo @@ -0,0 +1,83 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Decorators + +import java.util.LinkedList + +function simple_decorator = |func| { + return |a,b| -> func(a+1,b+1) +} + +@simple_decorator +function simple_adder = |x,y| -> x + y + +function decorator_with_params = |param1, param2|{ + return |func| { + return |a,b| -> func(a+param1,b+param2) + } +} + +@decorator_with_params(10,2) +function parametrized_adder = |x,y| -> x + y + +function generic_decorator = |func| { + return |args...| { + println("number of params : "+args: length()) + return func: invokeWithArguments(args) + } +} + +@generic_decorator +function generic_adder0 = -> 42 + +@generic_decorator +function generic_adder1 = |x| -> x + +@generic_decorator +function generic_adder2 = |x,y| -> x + y + +@generic_decorator +function generic_adder3 = |x,y,z| -> x + y + z + +function list_sum_decorator = |func| { + return |this| -> func(this) - 8 +} + +augment java.util.List { + + @list_sum_decorator + function sum = |this| { + var acc = 0 + foreach elem in this { + acc = acc + elem + } + return acc + } +} + +function main = |args| { + println(simple_adder(10,30)) + println(parametrized_adder(10,20)) + println(generic_adder0()) + println(generic_adder1(42)) + println(generic_adder2(20,22)) + println(generic_adder3(10,12,20)) + let list = LinkedList() + list: add(5) + list: add(10) + list: add(15) + list: add(20) + println(list: sum()) +} \ No newline at end of file diff --git a/samples/Golo/dynamic-evaluation.golo b/samples/Golo/dynamic-evaluation.golo new file mode 100755 index 00000000..af5351f4 --- /dev/null +++ b/samples/Golo/dynamic-evaluation.golo @@ -0,0 +1,88 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.DynamicEvaluation + +import gololang.EvaluationEnvironment + +local function test_asModule = |env| { + let code = +""" +module foo + +function a = -> "a!" +function b = -> "b!" +""" + let mod = env: asModule(code) + let a = fun("a", mod) + let b = fun("b", mod) + println(">>> asModule()") + println(a()) + println(b()) +} + +local function test_anonymousModule = |env| { + let code = +""" +function a = -> "a." +function b = -> "b." +""" + let mod = env: anonymousModule(code) + let a = fun("a", mod) + let b = fun("b", mod) + println(">>> anonymousModule()") + println(a()) + println(b()) +} + +local function test_asFunction = |env| { + let code = "return (a + b) * 2" + let f = env: asFunction(code, "a", "b") + println(">>> asFunction") + println(f(10, 20)) +} + +local function test_def = |env| { + let code = "|a, b| -> (a + b) * 2" + let f = env: def(code) + println(">>> def") + println(f(10, 20)) +} + +local function test_run = |env| { + let code = """println(">>> run") + foreach (i in range(0, 3)) { + println("w00t") + }""" + env: run(code) +} + +local function test_run_map = |env| { + let code = """println(">>> run_map") + println(a) + println(b) + """ + let values = java.util.TreeMap(): add("a", 1): add("b", 2) + env: run(code, values) +} + +function main = |args| { + let env = EvaluationEnvironment() + test_asModule(env) + test_anonymousModule(env) + test_asFunction(env) + test_def(env) + test_run(env) + test_run_map(env) +} diff --git a/samples/Golo/dynamic-object-person.golo b/samples/Golo/dynamic-object-person.golo new file mode 100755 index 00000000..27f3ab6d --- /dev/null +++ b/samples/Golo/dynamic-object-person.golo @@ -0,0 +1,29 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.DynamicObjectPerson + +local function mrbean = -> DynamicObject(): + name("Mr Bean"): + email("mrbean@gmail.com"): + define("toString", |this| -> this: name() + " <" + this: email() + ">") + +function main = |args| { + + let bean = mrbean() + println(bean: toString()) + + bean: email("mrbean@outlook.com") + println(bean: toString()) +} diff --git a/samples/Golo/echo-args.golo b/samples/Golo/echo-args.golo new file mode 100755 index 00000000..7bf1e093 --- /dev/null +++ b/samples/Golo/echo-args.golo @@ -0,0 +1,34 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module EchoArgs + +function main = |args| { + + println("With a for loop and an index:") + for (var i = 0, i < args: length(), i = i + 1) { + println(" #" + i + " -> " + args: get(i)) + } + + println("With a foreach loop:") + foreach arg in args { + println(" " + arg) + } + + println("With a foreach over a range:") + foreach i in range(0, args: length()) { + println(" #" + i + " -> " + args: get(i)) + } +} + diff --git a/samples/Golo/enums-thread-state.golo b/samples/Golo/enums-thread-state.golo new file mode 100755 index 00000000..4310ea26 --- /dev/null +++ b/samples/Golo/enums-thread-state.golo @@ -0,0 +1,31 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module sample.EnumsThreadState + +import java.lang.Thread$State + +function main = |args| { + + # Call the enum entry like a function + let new = Thread$State.NEW() + println("name=" + new: name() + ", ordinal=" + new: ordinal()) + println("-----------") + + # Walk through all enum entries + foreach element in Thread$State.values() { + println("name=" + element: name() + ", ordinal=" + element: ordinal()) + } +} + diff --git a/samples/Golo/fibonacci.golo b/samples/Golo/fibonacci.golo new file mode 100755 index 00000000..53455a7d --- /dev/null +++ b/samples/Golo/fibonacci.golo @@ -0,0 +1,39 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Fibonacci + +import java.lang.System + +function fib = |n| { + if n <= 1 { + return n + } else { + return fib(n - 1) + fib(n - 2) + } +} + +local function run = { + let start = System.currentTimeMillis() + let result = fib(40) + let duration = System.currentTimeMillis() - start + println(">>> " + result + " (took " + duration + "ms)") +} + +function main = |args| { + while true { + run() + } +} + diff --git a/samples/Golo/helloworld.golo b/samples/Golo/helloworld.golo new file mode 100755 index 00000000..4800de6d --- /dev/null +++ b/samples/Golo/helloworld.golo @@ -0,0 +1,20 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module hello.World + +function main = |args| { + println("Hello world!") +} + diff --git a/samples/Golo/http-server.golo b/samples/Golo/http-server.golo new file mode 100755 index 00000000..ce4ff857 --- /dev/null +++ b/samples/Golo/http-server.golo @@ -0,0 +1,53 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.WebServer + +import java.lang +import java.net.InetSocketAddress +import com.sun.net.httpserver +import com.sun.net.httpserver.HttpServer + +function main = |args| { + + let server = HttpServer.create(InetSocketAddress("localhost", 8081), 0) + + server: createContext("/", |exchange| { + let headers = exchange: getResponseHeaders() + let response = StringBuilder(): + append("Requested URI: "): + append(exchange: getRequestURI()): + append("\n"): + append("Current time: "): + append(java.util.Date()): + append("\n"): + toString() + headers: set("Content-Type", "text/plain") + exchange: sendResponseHeaders(200, response: length()) + exchange: getResponseBody(): write(response: getBytes()) + exchange: close() + }) + + server: createContext("/shutdown", |exchange| { + let response = "Ok, thanks, bye!" + exchange: getResponseHeaders(): set("Content-Type", "text/plain") + exchange: sendResponseHeaders(200, response: length()) + exchange: getResponseBody(): write(response: getBytes()) + exchange: close() + server: stop(5) + }) + + server: start() + println(">>> http://localhost:8081/") +} diff --git a/samples/Golo/logdeco.golo b/samples/Golo/logdeco.golo new file mode 100755 index 00000000..ae42a133 --- /dev/null +++ b/samples/Golo/logdeco.golo @@ -0,0 +1,65 @@ + +module samples.LogDeco + +function log1 = |msg| { + return |fun| { + return |args...| { + println(msg) + return fun: invokeWithArguments(args) + } + } +} + +@log1("calling foo") +function foo = |a| { + println("foo got a " + a) +} + +@log1("I'am a bar") +function bar = |a| -> 2*a + +let sayHello = log1("Hello") + +@sayHello +function baz = -> "Goodbye" + +function log2 = |msgBefore| -> |msgAfter| -> |func| -> |args...| { + println(msgBefore) + let res = func: invokeWithArguments(args) + println(msgAfter) + return res +} + +@log2("enter foo")("exit foo") +function spam = |a| { + println("foo: " + a) +} + +function logEnterExit = |name| -> log2("# enter " + name)("# exit " + name) + +@logEnterExit("bar") +function egg = { println("doing something...") } + +function main = |args| { + + foo("bar") + + println("---") + println(bar(21)) + + println("---") + println(baz()) + + println("---") + spam("bar") + + println("---") + egg() + + println("---") + let strange_use = log2("hello")("goodbye")({println(":p")}) + strange_use() + + println("---") + log2("another")("use")(|a|{println(a)})("strange") +} diff --git a/samples/Golo/matching-operator.golo b/samples/Golo/matching-operator.golo new file mode 100755 index 00000000..380d2259 --- /dev/null +++ b/samples/Golo/matching-operator.golo @@ -0,0 +1,40 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Matching + +import java.util.LinkedList + +local function data = { + let list = LinkedList() + list: add("foo@bar.com") + list: add("+33.6.11.22.33") + list: add("http://golo-lang.org/") + list: add("def foo = bar(_._) with :> T") + return list +} + +local function what_it_could_be = |item| -> match { + when item: contains("@") then "an email?" + when item: startsWith("+33") then "a French phone number?" + when item: startsWith("http://") then "a website URL?" + otherwise "I have no clue, mate!" +} + +function main = |args| { + foreach item in data() { + println(item + " => " + what_it_could_be(item)) + } +} + diff --git a/samples/Golo/max-int.golo b/samples/Golo/max-int.golo new file mode 100755 index 00000000..457a5dff --- /dev/null +++ b/samples/Golo/max-int.golo @@ -0,0 +1,24 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.MaxInt + +local function max_int = { + return java.lang.Integer.MAX_VALUE() +} + +function main = |args| { + println(max_int()) +} + diff --git a/samples/Golo/memoize.golo b/samples/Golo/memoize.golo new file mode 100755 index 00000000..8fb1b455 --- /dev/null +++ b/samples/Golo/memoize.golo @@ -0,0 +1,55 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.MemoizeDecorator + +import gololang.Decorators + +import java.lang.System + +let memo = memoizer() + +@memo +function fib = |n| { + if n <= 1 { + return n + } else { + return fib(n - 1) + fib(n - 2) + } +} + +@memo +function foo = |n| -> n + +local function run = { + let start = System.currentTimeMillis() + let result = fib(40) + let duration = System.currentTimeMillis() - start + println(">>> fib(40) = " + result + " (took " + duration + "ms)") +} + +local function run2 = { + let start = System.currentTimeMillis() + let result = foo(40) + let duration = System.currentTimeMillis() - start + println(">>> foo(40) = " + result + " (took " + duration + "ms)") +} + +function main = |args| { + foreach i in range(0, 5) { + println("run " + i) + run() + run2() + } +} diff --git a/samples/Golo/null-safety.golo b/samples/Golo/null-safety.golo new file mode 100755 index 00000000..903f5309 --- /dev/null +++ b/samples/Golo/null-safety.golo @@ -0,0 +1,43 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module DealingWithNull + +import java.util + +function main = |args| { + + # Data model + let contacts = map[ + ["mrbean", map[ + ["email", "bean@gmail.com"], + ["url", "http://mrbean.com"] + ]], + ["larry", map[ + ["email", "larry@iamricherthanyou.com"] + ]] + ] + + # MrBean and Larry + let mrbean = contacts: get("mrbean") + let larry = contacts: get("larry") + + # Illustrates orIfNull + println(mrbean: get("url") orIfNull "n/a") + println(larry: get("url") orIfNull "n/a") + + # Querying a non-existent data model because there is no 'address' entry + println(mrbean: get("address")?: street()?: number() orIfNull "n/a") +} + diff --git a/samples/Golo/prepost-decorators.golo b/samples/Golo/prepost-decorators.golo new file mode 100755 index 00000000..a7ea73ca --- /dev/null +++ b/samples/Golo/prepost-decorators.golo @@ -0,0 +1,65 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.PrepostDecorator + +import gololang.Decorators + +let isInteger = isOfType(Integer.class) + +@checkResult(isString(): andThen(lengthIs(2))) +@checkArguments(isInteger: andThen(isPositive()), isString()) +function foo = |a, b| { + return b + a +} + +let myCheck = checkArguments(isInteger: andThen(isPositive())) + +@myCheck +function inv = |v| -> 1.0 / v + +let isPositiveInt = isInteger: andThen(isPositive()) + +@checkArguments(isPositiveInt) +function mul = |v| -> 10 * v + +@checkArguments(isNumber()) +function num = |v| -> "ok" + +@checkArguments(isNotNull()) +function notnull = |v| -> "ok" + +function main = |args| { + try { println(foo(1, "b")) } catch (e) { println(e) } + try { println(foo(-1, "b")) } catch (e) { println(e) } + try { println(foo("a", 2)) } catch (e) { println(e) } + try { println(foo(1, 2)) } catch (e) { println(e) } + try { println(foo(10, "ab")) } catch (e) { println(e) } + + try { println(inv(10)) } catch (e) { println(e) } + try { println(inv(0)) } catch (e) { println(e) } + + try { println(mul(5)) } catch (e) { println(e) } + try { println(mul(0)) } catch (e) { println(e) } + + try { println(num(1)) } catch (e) { println(e) } + try { println(num(1_L)) } catch (e) { println(e) } + try { println(num(1.5)) } catch (e) { println(e) } + try { println(num(1.5_F)) } catch (e) { println(e) } + try { println(num("a")) } catch (e) { println(e) } + try { println(num('a')) } catch (e) { println(e) } + + try { println(notnull('1')) } catch (e) { println(e) } + try { println(notnull(null)) } catch (e) { println(e) } +} diff --git a/samples/Golo/structs.golo b/samples/Golo/structs.golo new file mode 100755 index 00000000..de18836a --- /dev/null +++ b/samples/Golo/structs.golo @@ -0,0 +1,69 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module StructDemo + +struct Point = { x, y } + +augment StructDemo.types.Point { + + function move = |this, offsetX, offsetY| { + this: x(this: x() + offsetX) + this: y(this: y() + offsetY) + return this + } + + function relative = |this, offsetX, offsetY| -> Point(this: x() + offsetX, this: y() + offsetY) +} + +function main = |args| { + + let p1 = Point(1, 2) + let p2 = Point(): x(1): y(2) + let p3 = p1: frozenCopy() + let p4 = p1: frozenCopy() + + println(p1) + println("x = " + p1: x()) + println("y = " + p1: y()) + + println("p1 == p2 " + (p1 == p2)) + println("p1 == p3 " + (p1 == p3)) + println("p3 == p4 " + (p3 == p4)) + + println("#p1 " + p1: hashCode()) + println("#p2 " + p2: hashCode()) + println("#p3 " + p3: hashCode()) + println("#p4 " + p4: hashCode()) + + println("p1: members() " + p1: members()) + println("p1: values() " + p1: values()) + foreach item in p1 { + println(item: get(0) + " -> " + item: get(1)) + } + + println("p1: set(\"x\", 10) " + p1: set("x", 10)) + println("p1: move(10, 5) " + p1: move(10, 5)) + println("p1: relative(11, 6) " + p1: relative(11, 6)) + + let p5 = ImmutablePoint(10, 20) + println("p5: " + p5) + try { + p5: x(100) + } catch (expected) { + println("p5 is immutable, so... " + expected: getMessage()) + } +} + + diff --git a/samples/Golo/swing-actionlistener.golo b/samples/Golo/swing-actionlistener.golo new file mode 100755 index 00000000..61d0f7f3 --- /dev/null +++ b/samples/Golo/swing-actionlistener.golo @@ -0,0 +1,43 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.SwingActionListener + +import java.awt.event +import javax.swing +import javax.swing.WindowConstants + +local function listener = |handler| -> asInterfaceInstance(ActionListener.class, handler) + +function main = |args| { + + let frame = JFrame("Action listeners") + frame: setDefaultCloseOperation(EXIT_ON_CLOSE()) + + let button = JButton("Click me!") + button: setFont(button: getFont(): deriveFont(96.0_F)) + + # Using a helper function + button: addActionListener(listener(|event| -> println("Clicked!"))) + + # Using a standard augmentation: MethodHandle::to(Class) + button: addActionListener((|event| -> println("[click]")): to(ActionListener.class)) + + # Straight closure passing + button: addActionListener(|event| -> println("( )")) + + frame: getContentPane(): add(button) + frame: pack() + frame: setVisible(true) +} diff --git a/samples/Golo/swing-helloworld.golo b/samples/Golo/swing-helloworld.golo new file mode 100755 index 00000000..9d5e0541 --- /dev/null +++ b/samples/Golo/swing-helloworld.golo @@ -0,0 +1,31 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.SwingHelloWorld + +import javax.swing +import javax.swing.WindowConstants + +function main = |args| { + + let frame = JFrame("Hello world") + frame: setDefaultCloseOperation(EXIT_ON_CLOSE()) + + let label = JLabel("Hello world") + label: setFont(label: getFont(): deriveFont(128.0_F)) + + frame: getContentPane(): add(label) + frame: pack() + frame: setVisible(true) +} diff --git a/samples/Golo/templates-chat-webapp.golo b/samples/Golo/templates-chat-webapp.golo new file mode 100755 index 00000000..a5eab98b --- /dev/null +++ b/samples/Golo/templates-chat-webapp.golo @@ -0,0 +1,90 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.TemplatesChatWebapp + +import java.lang +import java.io +import java.net.InetSocketAddress +import com.sun.net.httpserver +import com.sun.net.httpserver.HttpServer + +local function redirect = |exchange, to| { + exchange: getResponseHeaders(): set("Location", to) + exchange: sendResponseHeaders(303, 0) + exchange: close() +} + +local function respond = |exchange, body| { + exchange: getResponseHeaders(): set("Content-Type", "text/html") + exchange: sendResponseHeaders(200, body: length()) + exchange: getResponseBody(): write(body: getBytes()) + exchange: close() +} + +# This is leaky and works with just 1 POST parameter... +local function extract_post = |exchange, posts| { + let reader = BufferedReader(InputStreamReader(exchange: getRequestBody())) + var line = reader: readLine() + while line isnt null { + if line: startsWith("msg=") { + posts: add(java.net.URLDecoder.decode(line: substring(4), "UTF-8")) + } + line = reader: readLine() + } + reader: close() +} + + +local function index = |posts, template, exchange| { + if exchange: getRequestMethod() == "POST" { + extract_post(exchange, posts) + redirect(exchange, "/") + } else { + respond(exchange, template(posts)) + } +} + +local function index_template = -> """ +<%@params posts %> + + + + Golo Chat + + +
+ + +
+
+

Last posts

+ <% foreach post in posts { %> +
+ <%= post %> +
+ <% } %> +
+ + +""" + +function main = |args| { + let index_tpl = gololang.TemplateEngine(): compile(index_template()) + let posts = java.util.concurrent.ConcurrentLinkedDeque() + let server = HttpServer.create(InetSocketAddress("localhost", 8081), 0) + server: createContext("/", ^index: bindTo(posts): bindTo(index_tpl)) + server: start() + println(">>> http://localhost:8081/") +} diff --git a/samples/Golo/util-containers.golo b/samples/Golo/util-containers.golo new file mode 100755 index 00000000..63d09b6a --- /dev/null +++ b/samples/Golo/util-containers.golo @@ -0,0 +1,51 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module MoreCoolContainers + +function main = |args| { + + println(">>> DynamicVariable") + + let dyn = DynamicVariable("Foo") + println(dyn: value()) + + let t1 = Thread({ + dyn: withValue(666, { + println(dyn: value()) + }) + }) + + let t2 = Thread({ + dyn: withValue(69, { + println(dyn: value()) + }) + }) + + t1: start() + t2: start() + t1: join() + t2: join() + println(dyn: value()) + + println(">>> Observable") + + let foo = Observable("Foo") + foo: onChange(|v| -> println("foo = " + v)) + + let mapped = foo: map(|v| -> v + "!") + mapped: onChange(|v| -> println("mapped = " + v)) + + foo: set("69") +} diff --git a/samples/Golo/workers.golo b/samples/Golo/workers.golo new file mode 100755 index 00000000..8c08f650 --- /dev/null +++ b/samples/Golo/workers.golo @@ -0,0 +1,48 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Workers + +import java.lang.Thread +import java.util.concurrent +import gololang.concurrent.workers.WorkerEnvironment + +local function pusher = |queue, message| -> queue: offer(message) + +local function generator = |port, message| { + foreach i in range(0, 100) { + port: send(message) + } +} + +function main = |args| { + + let env = WorkerEnvironment.builder(): withFixedThreadPool() + let queue = ConcurrentLinkedQueue() + + let pusherPort = env: spawn(^pusher: bindTo(queue)) + let generatorPort = env: spawn(^generator: bindTo(pusherPort)) + + let finishPort = env: spawn(|any| -> env: shutdown()) + + foreach i in range(0, 10) { + generatorPort: send("[" + i + "]") + } + Thread.sleep(2000_L) + finishPort: send("Die!") + + env: awaitTermination(2000) + println(queue: reduce("", |acc, next| -> acc + " " + next)) +} + diff --git a/samples/Graphviz (DOT)/annoying.DOT b/samples/Graphviz (DOT)/annoying.DOT new file mode 100644 index 00000000..fd20f4a4 --- /dev/null +++ b/samples/Graphviz (DOT)/annoying.DOT @@ -0,0 +1,50 @@ +/* + Huffman Tree DOT graph. + + DOT Reference : http://www.graphviz.org/doc/info/lang.html + http://en.wikipedia.org/wiki/DOT_language + Timestamp : 1415989074 + Phrase : 'OH GOD WHY IS LINGUIST SO ANAL ABOUT THIS STUFF' + + Generated on http://huffman.ooz.ie/ +*/ + +digraph G { + edge [label=0]; + graph [ranksep=0]; + T [shape=record, label="{{T|4}|000}"]; + S [shape=record, label="{{S|5}|001}"]; + SPACE [shape=record, label="{{SPACE|9}|01}"]; + A [shape=record, label="{{A|3}|1000}"]; + H [shape=record, label="{{H|3}|1001}"]; + U [shape=record, label="{{U|3}|1010}"]; + L [shape=record, label="{{L|2}|10110}"]; + N [shape=record, label="{{N|2}|10111}"]; + I [shape=record, label="{{I|4}|1100}"]; + O [shape=record, label="{{O|4}|1101}"]; + G [shape=record, label="{{G|2}|11100}"]; + F [shape=record, label="{{F|2}|11101}"]; + GF [label=4]; + W [shape=record, label="{{W|1}|111100}"]; + Y [shape=record, label="{{Y|1}|111101}"]; + B [shape=record, label="{{B|1}|111110}"]; + D [shape=record, label="{{D|1}|111111}"]; + BD [label=2]; + WYBD [label=4]; + GFWYBD [label=8]; + 47 -> 18 -> 9 -> T; + 29 -> 13 -> 6 -> A; + 7 -> U; + 4 -> L; + 16 -> 8 -> I; + GFWYBD -> GF -> G; + WYBD -> 2 -> W; + BD -> B;9 -> S [label=1]; + 18 -> SPACE [label=1]; + 6 -> H [label=1]; + 13 -> 7 -> 4 -> N [label=1]; + 8 -> O [label=1]; + GF -> F [label=1]; + 2 -> Y [label=1]; + 47 -> 29 -> 16 -> GFWYBD -> WYBD -> BD -> D [label=1]; +} \ No newline at end of file diff --git a/samples/Graphviz (DOT)/sample.dot b/samples/Graphviz (DOT)/sample.dot new file mode 100644 index 00000000..a55dc093 --- /dev/null +++ b/samples/Graphviz (DOT)/sample.dot @@ -0,0 +1,74 @@ +/* + Huffman Tree DOT graph. + + DOT Reference : http://www.graphviz.org/doc/info/lang.html + http://en.wikipedia.org/wiki/DOT_language + Timestamp : 1415988139 + Phrase : 'SERIAL KILLER AND SEX OFFENDER ANGUS SINCLAIR IS JAILED FOR A MINIMUM OF 37 YEARS FOR THE 1977 WORLDS END MURDERS OF HELEN SCOTT AND CHRISTINE EADIE.' + + Generated on http://huffman.ooz.ie/ +*/ + +digraph G { + edge [label=0]; + graph [ranksep=0]; + node [shape=record]; + U [label="{{U|3}|00000}"]; + G [label="{{G|1}|0000100}"]; + K [label="{{K|1}|0000101}"]; + _3 [label="{{3|1}|0000110}"]; + _9 [label="{{9|1}|0000111}"]; + _39 [label=2]; + L [label="{{L|7}|0001}"]; + O [label="{{O|7}|0010}"]; + Y [label="{{Y|1}|0011000}"]; + X [label="{{X|1}|0011001}"]; + YX [label=2]; + J [label="{{J|1}|0011010}"]; + W [label="{{W|1}|0011011}"]; + JW [label=2]; + YXJW [label=4]; + M [label="{{M|4}|00111}"]; + E [label="{{E|15}|010}"]; + D [label="{{D|8}|0110}"]; + T [label="{{T|4}|01110}"]; + DOT [label="{{DOT|1}|0111100}"]; + _1 [label="{{1|1}|0111101}"]; + DOT1 [label=2]; + _7 [label="{{7|3}|011111}"]; + A [label="{{A|9}|1000}"]; + N [label="{{N|9}|1001}"]; + S [label="{{S|10}|1010}"]; + I [label="{{I|11}|1011}"]; + R [label="{{R|11}|1100}"]; + C [label="{{C|3}|110100}"]; + H [label="{{H|3}|110101}"]; + F [label="{{F|6}|11011}"]; + SPACE [label="{{SPACE|26}|111}"]; + 149 -> 61 -> 29 -> 14 -> 7 -> U; + 4 -> 2 -> G; + _39 -> _3; + 15 -> O; + 8 -> YXJW -> YX -> Y; + JW -> J; + 32 -> E; + 17 -> D; + 9 -> T; + 5 -> DOT1 -> DOT; + 88 -> 39 -> 18 -> A; + 21 -> S; + 49 -> 23 -> R; + 12 -> 6 -> C;2 -> K [label=1]; + 7 -> 4 -> _39 -> _9 [label=1]; + 14 -> L [label=1]; + YX -> X [label=1]; + YXJW -> JW -> W [label=1]; + 29 -> 15 -> 8 -> M [label=1]; + DOT1 -> _1 [label=1]; + 61 -> 32 -> 17 -> 9 -> 5 -> _7 [label=1]; + 18 -> N [label=1]; + 39 -> 21 -> I [label=1]; + 6 -> H [label=1]; + 23 -> 12 -> F [label=1]; + 149 -> 88 -> 49 -> SPACE [label=1]; +} \ No newline at end of file diff --git a/samples/HTML/example.xht b/samples/HTML/example.xht new file mode 100644 index 00000000..a49a0a53 --- /dev/null +++ b/samples/HTML/example.xht @@ -0,0 +1,17 @@ + + + + This is a XHTML sample file + + + +
+ Just a simple XHTML test page. +
+ + + diff --git a/samples/Hack/Assert.hh b/samples/Hack/Assert.hh new file mode 100644 index 00000000..c80fc87a --- /dev/null +++ b/samples/Hack/Assert.hh @@ -0,0 +1,55 @@ +( + (function(mixed): T) $fn, + mixed $x, + ): array { + if (is_array($x)) { + return array_map($fn, $x); + } + throw new AssertException('Expected an array'); + } +} diff --git a/samples/Hack/AssertRecipe.hh b/samples/Hack/AssertRecipe.hh new file mode 100644 index 00000000..e2f9eabd --- /dev/null +++ b/samples/Hack/AssertRecipe.hh @@ -0,0 +1,52 @@ +> + protected function getDescription(): ?string { + return 'When you have values with unknown types, it is useful to make '. + 'some runtime assertions and have the type checker understand. This '. + 'recipe demonstrates one approach.'; + } + + protected function getFilenames(): Vector { + return Vector { + 'Assert.php', + }; + } + + protected function getDocs(): Vector<(string, string)> { + return Vector{ + tuple ('Mixed Types', 'hack.annotations.mixedtypes'), + tuple ('Type Inference', 'hack.otherrulesandfeatures.typeinference'), + }; + } + + public function getDemoFilename(): string { + return 'demo.php'; + } + + public function getDemoResult(): string { + return assert_main(); + } + + public function getDemoXHP(): ?:xhp { + return null; + } +} diff --git a/samples/Hack/Controller.hh b/samples/Hack/Controller.hh new file mode 100644 index 00000000..a21aacb2 --- /dev/null +++ b/samples/Hack/Controller.hh @@ -0,0 +1,39 @@ +; + abstract protected function getJS(): Set; + abstract protected function getTitle(): string; + abstract protected function render(): :xhp; + + final protected function getHead(): :xhp { + $css = $this->getCSS()->toVector()->map( + ($css) ==> + ); + $js = $this->getJS()->toVector()->map( + ($js) ==>