Compare commits

..

132 Commits

Author SHA1 Message Date
Brandon Black
f7fe1fee66 Release v5.0.5 -- part Deux (#3479)
* bumping to v5.0.5

* relaxing rugged version requirement
2017-02-15 21:29:04 -08:00
Brandon Black
94367cc460 Update LICENSE 2017-02-15 14:11:37 -08:00
Phineas
72bec1fddc Update LICENSE Copyright Date to 2017 (#3476) 2017-02-15 14:11:13 -08:00
Brandon Black
4e2eba4ef8 Revert "Release v5.0.5" (#3477) 2017-02-15 12:48:45 -08:00
Colin Seymour
10457b6639 Release v5.0.5 (#3473)
Release v5.0.5

* Update submodules

* Update grammars

* Bump version to 5.0.5

* Relax dependency on rugged

It's probably not wise to depend on a beta version just yet.

* revert php.tmbundle grammar update

One of the changes in 3ed4837b43...010cc1c22c leads to breakage in snippet highlighting on github.com
2017-02-15 11:12:53 +00:00
Colin Seymour
01de40faaa Return early in Classifier.classify if no languages supplied (#3471)
* Return early if no languages supplied

There's no need to tokenise the data when attempting to classify without a limited language scope as no action will be performed when it comes to scoring anyway.

* Add test for empty languages array
2017-02-13 18:22:54 +00:00
Paul Chaignon
62d285fce6 Fix head commit for TXL grammar (#3470) 2017-02-13 14:35:38 +01:00
Stefan Stölzle
0056095e8c Add .lkml to LookML (#3454)
* Add .lkml to LookML

* Limit .lkml to .view.lkml and .model.lkml

* Add lkml samples

* Fix extension order
2017-02-03 11:50:30 +01:00
Lars Brinkhoff
d6dc3a3991 Accomodate Markdown lines which begin with '>'. (#3452) 2017-02-02 11:58:52 -08:00
Greg Zimmerman
b524461b7c Add PowerShell color. Matches default console color for PowerShell. (#3448) 2017-02-02 11:13:01 -08:00
fix-fix
76d41697aa Use official HTML primary color (#3447)
Use primary color of HTML5 logo as defined on Logo FAQ page
2017-02-02 11:09:55 -08:00
John Gardner
32147b629e Register "Emakefile" as an Erlang filename (#3443) 2017-02-02 11:09:07 -08:00
John Gardner
e7b5e25bf8 Add support for regular expression data (#3441) 2017-02-02 11:08:20 -08:00
Brandon Black
d761658f8b Release v5.0.4 (#3445)
* bumping to v5.0.3

* updating rugged
2017-01-31 15:08:52 -08:00
Brandon Black
3719214aba fixing null reference in yarn.lock check (#3444) 2017-01-31 14:45:22 -08:00
Paul Chaignon
47b109be36 Improve heuristic for Modula-2 (#3434)
Module names can contain dots
2017-01-24 15:10:46 -08:00
Javier Honduvilla Coto
1ec4db97c2 Be able to configure the number of threads for git submodules update (#3438)
* make the number of submodule update threads configurable

* change thread number to be a script argument
2017-01-24 09:55:31 -08:00
Brandon Black
9fe5fe0de2 v5.0.3 Release (#3436)
* bumping to v5.0.3

* updating grammars
2017-01-23 20:09:26 -08:00
sunderls
b36ea7ac9d Add yarn (#3432)
* add yarn.lock

* fix comment

* remove yarn test

* add test

* fix test

* try fix again

* try 3rd time

* check filename and firstline for yarn lockfile
2017-01-23 10:58:53 -08:00
Yuki Izumi
625b06c30d Use textmate/diff.tmbundle again (#3429)
Upstream textmate/diff.tmbundle#6 was merged.
2017-01-17 17:02:10 +11:00
Brandon Black
28bce533b2 Release v5.0.2 (#3427)
* updated grammars

* bumping version

* adding .gem files to gitignore
2017-01-11 16:08:31 -08:00
John Gardner
93ec1922cb Swap grammar used for CSS highlighting (#3426)
* Swap grammar used for CSS highlighting

* Whitelist license of Atom's CSS grammar

* Explicitly declare grammar as MIT-licensed

Source: https://github.com/atom/language-css/blob/5d4af/package.json#L14
2017-01-11 16:16:25 +11:00
Yuki Izumi
5d09fb67dd Allow for split(",") returning nil (#3424) 2017-01-10 11:44:24 +11:00
Arfon Smith
93dcb61742 Removing references to @arfon (#3423) 2017-01-09 11:54:55 -08:00
Brandon Black
3a03594685 bumping to v5.0.1 (#3421) 2017-01-08 23:30:56 -08:00
Brandon Black
5ce2c254f9 purging vestigial search term references 2017-01-08 23:08:16 -08:00
Brandon Black
d7814c4899 fixing incompatibility with latest rugged 2017-01-08 22:59:00 -08:00
Brandon Black
50c08bf29e updating grammars 2017-01-08 22:29:01 -08:00
Yuki Izumi
34928baee6 Use https://github.com/textmate/diff.tmbundle/pull/6 (#3420) 2017-01-08 21:53:14 -08:00
USAMI Kenta
27bb41aa4d Add Cask file as Emacs Lisp (#3416)
* Add Cask file as Emacs Lisp

* Replace Cask file (original is zonuexe/composer.el)
2017-01-04 11:26:20 -08:00
Brandon Black
1415f4b52d fixing grammar file pedantry 2017-01-03 17:23:56 -08:00
Arie Kurniawan
ae8ffcad22 change http to https
fix the little flaws found on http protocol that is used,
one of the web using the http protocol which is already supporting more secure protocol,
which is https
2017-01-03 17:19:58 -08:00
Brandon Black
f43633bf10 fixing license for atom-language-rust 2017-01-03 17:02:25 -08:00
Brandon Black
a604de9846 replacing atom grammar due to ST2 compatibility change 2017-01-03 16:46:02 -08:00
Brandon Black
3e224e0039 updating grammars 2017-01-03 16:33:46 -08:00
Christopher Gilbert
15b04f86c3 Amended license file for SublimeEthereum language grammar 2017-01-03 16:13:27 -08:00
Christopher Gilbert
42af436c20 Added grammar for Solidity programming language 2017-01-03 16:13:27 -08:00
Christopher Gilbert
2b08c66f0b Added grammar for Solidity programming language 2017-01-03 16:13:27 -08:00
Zach Brock
f98ab593fb Detect Javascript files generated by Protocol Buffers. 2017-01-03 16:07:26 -08:00
Brandon Black
f951ec07de bin help cleanup 2017-01-03 15:52:22 -08:00
Vadim Markovtsev
e9ac71590f Add --json option to bin/linguist 2017-01-03 14:56:12 -08:00
Al Thomas
210cd19876 Add Genie programming language (#3396)
* Add Genie programming language

Genie was introduced in 2008 as part of the GNOME project:
https://wiki.gnome.org/Projects/Genie

It is a programming language that uses the Vala compiler to
produce native binaries. It has good bindings to C libraries
especially those that are part of the GObject world such as
Gtk+3 and GStreamer

* Change color for Genie so tests pass
2017-01-03 14:15:17 -08:00
Mate Lorincz
f473c555ac Update vendor.yml (#3382)
Exclude Realm and RealmSwift frameworks from language statistics.
2017-01-03 14:10:49 -08:00
Nate Whetsell
48e4394d87 Add Jison-generated JavaScript to generated files (#3393)
* Fix typos

* Add Jison-generated JavaScript to generated files
2017-01-03 14:08:29 -08:00
meganemura
e1ce88920d Fix add-grammar and convert-grammars (#3354)
* Skip removed grammar submodule

* Clean up old grammar from grammars and grammars.yml

* Clean up unused grammar license

Run `script/licensed`.
This was missing change in 12f9295 of #3350.

* Clean up license files when we replace grammar

Update license files by running `script/licensed`.
Since we replace grammar, the old grammar license must be removed
and new grammar license must be added.
2017-01-03 13:57:46 -08:00
Paul Chaignon
675cee1d72 Improve the .pl Prolog heuristic rule (#3409)
:- can be directly at the start of a line
2017-01-03 13:54:47 -08:00
yutannihilation
1c4baf6dc2 ignore roxygen2-generated files (#3373) 2017-01-03 13:31:04 -08:00
Samantha McVey
8f2820e9cc Add XCompose language and highlighter (#3402)
* Add XCompose language and highlighter

* XCompose fix some errors in the Travis build

* Remove xmodmap files for XCompose

Most xmodmap files aren't XCompose, and there's not enough xmodmap files
which are XCompose to be worth adding to heuristics

* Remove some extensions/filenames from XCompose

* Rename and move sample to correct folder and filename

That we have added in languages.yml

* Use generated language id
2017-01-03 13:29:00 -08:00
Danila Malyutin
04c268e535 Add mysql extension for sql scripts (#3413) 2017-01-03 11:47:19 -08:00
Paul Chaignon
ec749b3f8d Remove the Hy grammar (#3411)
The grammar repository was recently deleted
2017-01-03 11:38:44 -08:00
Samantha McVey
08b63e7033 Change repository for Perl 6 grammar 2016-12-24 00:58:21 +01:00
Darin Morrison
7867b946b9 Add support for Reason (#3336) 2016-12-22 17:03:18 -08:00
Brandon Black
a4d12cc8e4 Release v5.0.0 (#3388)
* bumping version to v5.0.0

* updating license information

* reverting accidental changes to language ids cc @twp

* Updating grammars
2016-12-22 16:55:22 -08:00
Brandon Black
a1165b74b1 reverting accidental changes to language ids cc @twp 2016-12-15 13:56:09 -08:00
Brandon Black
0fa1fa5581 fixing groff reference 2016-12-14 10:19:39 -08:00
Arfon Smith
d8b91bd5c4 The grand language renaming bonanza (#3278)
* Removing FORTRAN samples because OS X case-insensitive filesystems :-\

* Adding Fotran samples back

* FORTRAN -> Fortran

* Groff -> Roff

* GAS -> Unix Assembly

* Cucumber -> Gherkin

* Nimrod -> Nim

* Ragel in Ruby Host -> Ragel

* Jade -> Pug

* VimL -> Vim script
2016-12-13 13:39:27 -08:00
Paul Chaignon
9b941a34f0 Use filenames as a definitive answer (#2006)
* Separate find_by_extension and find_by_filename
find_by_extension now takes a path as argument and not only the file extension.
Currently only find_by_extension is used as a strategy.

* Add find_by_filename as first strategy
2016-12-12 12:34:33 -08:00
Paul Chaignon
9d8392dab8 Remove deprecated code (#3359)
* Remove deprecated find_by_shebang

* Remove deprecated ace_modes function

* Remove deprecated primary_extension function

Gists don't have a language dropdown anymore

* Remove deprecated Linguist::Language.detect function

* Remove deprecated search_term field
2016-12-12 12:24:19 -08:00
Brandon Black
2c78dd2c66 Bumping to v4.8.18 (#3370)
* make tests great again 

* version bump

* removing empty line in gemspec
2016-12-07 11:39:49 -08:00
Brandon Black
3988f3e7a7 Merge branch 'rascal-linguist' of git://github.com/ahmadsalim/linguist into ahmadsalim-rascal-linguist 2016-12-07 09:28:40 -08:00
USAMI Kenta
d9a4e831b4 Add .php_cs and .php_cs.dist (#3367)
* Add .php_cs and .php_cs.dist

* Move files to filenames subdir
2016-12-07 09:20:40 -08:00
John Gardner
45c27f26a2 Add support for the GN configuration language (#3368)
* Add samples and definition for GN build files

* Add grammar to provide GN syntax highlighting

* Fix failing tests

* Add Python extensions for GYP includes and .gclient configs
2016-12-07 09:20:23 -08:00
Ahmad Salim Al-Sibahi
0fbc29bf68 Updated language id 2016-12-07 08:53:40 +01:00
Ahmad Salim Al-Sibahi
5569d2056d Removed old submodules 2016-12-07 08:47:40 +01:00
Ahmad Salim Al-Sibahi
be262d0b4f Merge remote-tracking branch 'refs/remotes/github/master'
Conflicts:
	.gitmodules
	grammars.yml
2016-12-07 08:36:48 +01:00
Brandon Black
33ce2d7264 Merge branch 'master' of https://github.com/github/linguist into meganemura-replace-haml 2016-12-06 22:13:40 -08:00
Paul Chaignon
c486f56204 Mark .indent.pro files as vendored (#3361) 2016-12-06 21:59:28 -08:00
Jim Deville
9f3b7d0ba5 Allow golang as an alias for Go code fences (#3221) 2016-12-06 21:55:25 -08:00
Paul Chaignon
79f20e8057 Heuristic rule for TeX .cls files (#3360) 2016-12-06 21:50:33 -08:00
Yamagishi Kazutoshi
cd30c7613c Detect .babelrc (#3358)
`.babelrc` is Babel configuration file in JSON 5 format.
2016-12-06 21:43:33 -08:00
John Gardner
5aa53c0711 Swap grammar used for Ninja highlighting (#3353) 2016-12-06 21:32:11 -08:00
Ahmad Salim Al-Sibahi
c17cdca896 Updated to the latest available grammar 2016-12-06 11:22:09 +01:00
Christoph Päper
ecdae83364 Add support for font-specific formats (#3142)
* markdown and font-specific updates languages.yml

- Markdown: ← extensions: .md.txt
- Text: ← extensions: .text
- Text: ← filenames: FONTLOG http://scripts.sil.org/cms/scripts/page.php?item_id=OFL-FAQ_web#43cecb44
- OpenType: ← extensions: .fea https://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html
- Spline Font: ← extensions: .sfd http://fontforge.github.io/en-US/documentation/developers/sfdformat/

* Update languages.yml

`type: data` for SFD

* Update languages.yml

OpenType feature ← type: markup

* Update languages.yml

alphabetic order

* Update languages.yml

incorporated suggestions:

- “OpenType Font Feature” → “Opentype feature” (no “file” at the end, because that’s left out almost everywhere else, too)
- `tm_scope` according to https://github.com/Alhadis/language-fontforge

* remove non-font related additions

- `.md.txt` Markdown
- `.text` Plain Text

* Update languages.yml

remove comment

* changed names as requested

* Merge remote-tracking branch 'github/master' into patch-2

# Conflicts:
#	lib/linguist/languages.yml

* quote marks

* Revert "Merge remote-tracking branch 'github/master' into patch-2"

This reverts commit 18e4256b828c4186fec806319cbf8b76f0d2c79b.

* Update language IDs

* Add missing submodule to grammars list
2016-12-05 18:50:05 -08:00
meganemura
31aafa2c78 Replace ruby-haml.tmbundle with language-haml
./script/add-grammar --replace ruby-haml.tmbundle https://github.com/ezekg/language-haml
2016-12-01 11:38:12 +09:00
Ahmad Salim Al-Sibahi
8a911b8ff3 Fixed ordering correctly 2016-11-30 00:15:17 +01:00
Ahmad Salim Al-Sibahi
9233f1d17f Fixed color, order and ace mode 2016-11-30 00:03:55 +01:00
Ahmad Salim Al-Sibahi
77eb36a982 Added Rascal Language Id 2016-11-29 23:42:02 +01:00
Ahmad Salim Al-Sibahi
4e6e58a099 Added Example Rascal files 2016-11-29 23:37:34 +01:00
Ahmad Salim Al-Sibahi
c87976330f Added Rascal Grammar Link 2016-11-29 23:15:16 +01:00
Simen Bekkhus
0e9109c3fc Add Nunjucks highlighting (#3341) 2016-11-29 10:14:25 -08:00
meganemura
12f9295dd7 Improve grammar scripts (#3350)
* Remove trailing spaces

* Setup Bundler in some scripts

* Update grammar index

* Make prune-grammars script to be callable in a script directory

* Prune unused xquery grammar repo

source.xq by language-jsoniq is actual tm_scope for XQuery.

* Remove xquery submodule

git submodule deinit vendor/grammars/xquery/
git rm vendor/grammars/xquery/

* Fix invocation of script/list-grammars

This fixes #3339.

* Make add-grammars script to be callable in a script directory

* Generate samples.json before running list-grammars

list-grammars requires linguist.
2016-11-29 10:13:33 -08:00
Santi Aguilera
581723748b Added Dangerfile for ruby (#3333)
* Added Dangerfile for ruby

* rm ant.tmbundle from wlist because has license

Travis output says ant.tmbundle has license, so Im removing it from the whitelist (projects without license)

* Added sample

* New line at EOF

* Fix

* Remove bad file
2016-11-29 08:01:35 -08:00
Paul Chaignon
0980e304b1 Generate language_id (#3284)
* Generate language_id from language names

The language_id is generated from the SHA256 hash of the language's name

* Test the validity of language ids

All languages should have a positive 32bit integer as an id

* Update languages.yml header in set-language-ids
2016-11-29 07:50:44 -08:00
Kyle Smith
d46a529b6a Add support for Thrift-generated PHP code. (#3329) 2016-11-29 07:49:41 -08:00
Paul Chaignon
1d2ec4dbc3 Fix error with filenames ending with a dot (#3349)
The second negative argument to split instructs it to
preserve null fields in the returned array
2016-11-29 07:42:50 -08:00
Brandon Black
829eea0139 Merge pull request #3337 from pchaigno/update-grammar-whitelist
Remove Ant from grammar whitelist
2016-11-21 17:13:29 -08:00
Paul Chaignon
78b2853d70 License of Ant grammar is correctly detected
The last version of Licensee can recognize
underlined license headers in READMEs
2016-11-18 23:47:55 +01:00
Ahmad Salim Al-Sibahi
202f3c08cd Started on adding support for rascal. 2016-11-14 14:29:30 +01:00
Brandon Black
b958779e3d Merge pull request #3325 from danilaml/py3-ext
Add py3 to Python's extensions list
2016-11-13 17:57:56 -08:00
Danila Malyutin
00dc775daf Update, according to comments 2016-11-12 22:01:31 +03:00
Danila Malyutin
009a4e67b6 add py3 extension to Python 2016-11-12 06:11:39 +03:00
Arfon Smith
faaa4470af Merge pull request #3297 from github/bye-bye-github
Not going to be staff for much longer.
2016-11-03 20:32:28 -04:00
Arfon Smith
2a320cb988 Adding new GitHub staff 2016-11-03 20:22:21 -04:00
Arfon Smith
74931d1bd5 Merge branch 'master' into bye-bye-github 2016-11-03 20:09:02 -04:00
Arfon Smith
3ca93a84b9 Merge pull request #3315 from github/cut-release-v4.8.17
v4.8.17 release PR
2016-11-02 15:20:00 -04:00
Arfon Smith
aa27f18ea6 Bumping version to v4.8.17 2016-11-02 13:33:16 -04:00
Arfon Smith
d3e2ea3f71 Grammar updates 2016-11-02 13:25:50 -04:00
Arfon Smith
53aa1209ab Merge pull request #3314 from github/coq-kiq
Replace GPL-licensed Coq samples
2016-11-02 13:13:44 -04:00
Arfon Smith
b2a486fed2 Merge pull request #3312 from sanssecours/ebnf
Add Support for EBNF
2016-11-02 13:07:34 -04:00
Alhadis
4f1e5c34b1 Add permissive-licensed Coq samples
BSD-2-Clause: https://github.com/jscert/jscert

  * JSCorrectness.v
  * JSInterpreterExtraction.v
  * JSNumber.v
  * JSPrettyInterm.v

MIT/Expat: https://github.com/clarus/coq-atm

  * Computation.v
  * Main.v
  * Spec.v
2016-11-03 02:50:54 +11:00
Alhadis
85c9833081 Delete GPL2.1-licensed Coq samples
These files are modified variants of the ones included in Coq's standard
distribution. The original materials feature the GPL 2.1 license in each
file's header, which was suspiciously removed from Linguist's samples.

    https://github.com/coq/coq/tree/trunk/theories

Basics.v is a different file to that found in Coq's distro, but is vague
in origin and being removed to err on the side of caution. The remaining
samples are from a MIT-licensed online course by Software Foundations:

    https://www.cis.upenn.edu/~bcpierce/sf/current/

References: github/linguist#3313
2016-11-03 02:32:23 +11:00
René Schwaiger
33899b9d6b Add support for EBNF
Extended Backus–Naur form ([EBNF][]) is a metalanguage used to specify
language grammars.

[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus–Naur_form
2016-11-02 13:50:30 +01:00
Arfon Smith
417239004a Merge pull request #3311 from sanssecours/abnf
Add Support for ABNF
2016-11-02 08:33:47 -04:00
René Schwaiger
6a1423d28f Add support for ABNF
Augmented Backus–Naur form ([ABNF][]) is a metalanguage used to specify
language grammars.

[ABNF]: https://en.wikipedia.org/wiki/Augmented_Backus–Naur_form
2016-11-02 12:52:16 +01:00
Arfon Smith
96a23ce388 Merge pull request #3092 from pchaigno/python-console
Support for Python console
2016-11-01 07:18:18 -04:00
Paul Chaignon
e8d7eed3aa Support for Python console 2016-11-01 11:21:00 +01:00
Arfon Smith
9d419c4ab9 Merge pull request #3245 from jecisc/smalltalk_examples
Add smalltalk samples
2016-10-30 12:31:37 -04:00
Arfon Smith
4eefc1f58e Merge pull request #3310 from github/welcoming-Alhadis
Adding @Alhadis to the maintainers list.
2016-10-30 08:41:59 -04:00
Arfon Smith
0b94b9cda7 Update CONTRIBUTING.md 2016-10-30 08:32:33 -04:00
Arfon Smith
c736038d94 Merge pull request #3308 from github/help-for-highlighting
Adding some language about grammars to the README
2016-10-29 09:41:08 -04:00
Arfon Smith
ec562138f8 More words 2016-10-29 09:40:33 -04:00
Arfon Smith
50013e8dd7 Words 2016-10-29 09:39:57 -04:00
Arfon Smith
416c5d1185 Update README.md 2016-10-29 08:58:57 -04:00
Arfon Smith
8869912d31 Merge pull request #3307 from github/3192-temp
3192  part deux
2016-10-29 08:40:10 -04:00
Arfon Smith
43fa563b77 Adding script/list-grammars to script/add-grammar 2016-10-29 08:33:58 -04:00
Arfon Smith
41c6aee8c3 Small readme edits 2016-10-29 08:30:09 -04:00
Alhadis
8cf575c37d Update grammars list 2016-10-29 13:05:59 +11:00
Alhadis
4e20928e04 Merge branch 'master' into grammar-list 2016-10-29 12:31:04 +11:00
Arfon Smith
3e37bd2680 Merge pull request #2843 from github/go-vendor
Go vendor
2016-10-28 00:24:06 -04:00
Arfon Smith
a29f5b2d46 Adding Go-specific vendor paths 2016-10-27 13:59:09 -04:00
Arfon Smith
4efc6f8c95 Merge branch 'master' into go-vendor 2016-10-26 18:34:02 -04:00
Arfon Smith
359699c454 Not going to be staff for much longer. 2016-10-26 13:55:19 -04:00
Cyril Ferlicot
bed8add2f5 Add smalltalk samples
(Issue: https://github.com/github/linguist/issues/3244)
2016-09-24 17:32:35 +02:00
Alhadis
3247d46e81 Chop trailing slashes before looking up language 2016-09-09 16:33:21 +10:00
Alhadis
9d57e1e1b5 Remove debugging vestige 2016-09-07 00:59:13 +10:00
Alhadis
2a4150b104 Butcher whitespace to appease tab-hating heretics 2016-09-07 00:23:31 +10:00
Alhadis
09612ae42e Add logic to update Markdown file 2016-09-07 00:21:05 +10:00
Alhadis
49e9ee48d0 Make grammar-listing code more modular 2016-09-07 00:09:24 +10:00
Alhadis
a8719f3e82 Add script to generate grammars-list in Markdown 2016-09-06 23:07:18 +10:00
Brandon Keepers
789607d9bc Merge branch 'master' into go-vendor
* master: (168 commits)
  ruby for example
  Bumping version
  Updating grammars
  Grammar for Less from Atom package
  Remove Less grammar
  Updating to latest perl6 grammar
  Adding Perl6-specific grammar.
  Grammar for YANG from Atom package
  Support for YANG language
  Add detection of GrammarKit-generated files
  Add .xproj to list of XML extensions
  Test submodules are using HTTPS links
  Improved vim modeline detection
  Heuristic for Pod vs. Perl
  Bumping to v4.7.4
  Grammar update
  Support .rs.in as a file extension for Rust files.
  HTTPS links for submodules
  Add the LFE lexer as an example of erlang .xrl
  Add the Elixir parser as an example of erlang .yrl
  ...
2016-02-18 20:12:27 -05:00
Brandon Keepers
d46530989c Only treat .go files in ^vendor/ as generated 2016-02-18 19:57:34 -05:00
Keith Rarick
3c5bcb434c Add Go dependencies to generated.rb and test_blob.rb 2015-09-03 10:27:28 -07:00
230 changed files with 39940 additions and 3076 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
*.gem
/Gemfile.lock /Gemfile.lock
.bundle/ .bundle/
.idea .idea

63
.gitmodules vendored
View File

@@ -130,9 +130,6 @@
[submodule "vendor/grammars/Sublime-Text-2-OpenEdge-ABL"] [submodule "vendor/grammars/Sublime-Text-2-OpenEdge-ABL"]
path = vendor/grammars/Sublime-Text-2-OpenEdge-ABL path = vendor/grammars/Sublime-Text-2-OpenEdge-ABL
url = https://github.com/jfairbank/Sublime-Text-2-OpenEdge-ABL url = https://github.com/jfairbank/Sublime-Text-2-OpenEdge-ABL
[submodule "vendor/grammars/sublime-rust"]
path = vendor/grammars/sublime-rust
url = https://github.com/jhasse/sublime-rust
[submodule "vendor/grammars/sublime-befunge"] [submodule "vendor/grammars/sublime-befunge"]
path = vendor/grammars/sublime-befunge path = vendor/grammars/sublime-befunge
url = https://github.com/johanasplund/sublime-befunge url = https://github.com/johanasplund/sublime-befunge
@@ -247,9 +244,6 @@
[submodule "vendor/grammars/cpp-qt.tmbundle"] [submodule "vendor/grammars/cpp-qt.tmbundle"]
path = vendor/grammars/cpp-qt.tmbundle path = vendor/grammars/cpp-qt.tmbundle
url = https://github.com/textmate/cpp-qt.tmbundle url = https://github.com/textmate/cpp-qt.tmbundle
[submodule "vendor/grammars/css.tmbundle"]
path = vendor/grammars/css.tmbundle
url = https://github.com/textmate/css.tmbundle
[submodule "vendor/grammars/d.tmbundle"] [submodule "vendor/grammars/d.tmbundle"]
path = vendor/grammars/d.tmbundle path = vendor/grammars/d.tmbundle
url = https://github.com/textmate/d.tmbundle url = https://github.com/textmate/d.tmbundle
@@ -325,9 +319,6 @@
[submodule "vendor/grammars/nemerle.tmbundle"] [submodule "vendor/grammars/nemerle.tmbundle"]
path = vendor/grammars/nemerle.tmbundle path = vendor/grammars/nemerle.tmbundle
url = https://github.com/textmate/nemerle.tmbundle url = https://github.com/textmate/nemerle.tmbundle
[submodule "vendor/grammars/ninja.tmbundle"]
path = vendor/grammars/ninja.tmbundle
url = https://github.com/textmate/ninja.tmbundle
[submodule "vendor/grammars/objective-c.tmbundle"] [submodule "vendor/grammars/objective-c.tmbundle"]
path = vendor/grammars/objective-c.tmbundle path = vendor/grammars/objective-c.tmbundle
url = https://github.com/textmate/objective-c.tmbundle url = https://github.com/textmate/objective-c.tmbundle
@@ -355,9 +346,6 @@
[submodule "vendor/grammars/r.tmbundle"] [submodule "vendor/grammars/r.tmbundle"]
path = vendor/grammars/r.tmbundle path = vendor/grammars/r.tmbundle
url = https://github.com/textmate/r.tmbundle url = https://github.com/textmate/r.tmbundle
[submodule "vendor/grammars/ruby-haml.tmbundle"]
path = vendor/grammars/ruby-haml.tmbundle
url = https://github.com/textmate/ruby-haml.tmbundle
[submodule "vendor/grammars/scheme.tmbundle"] [submodule "vendor/grammars/scheme.tmbundle"]
path = vendor/grammars/scheme.tmbundle path = vendor/grammars/scheme.tmbundle
url = https://github.com/textmate/scheme.tmbundle url = https://github.com/textmate/scheme.tmbundle
@@ -449,9 +437,6 @@
[submodule "vendor/grammars/Sublime-Nit"] [submodule "vendor/grammars/Sublime-Nit"]
path = vendor/grammars/Sublime-Nit path = vendor/grammars/Sublime-Nit
url = https://github.com/R4PaSs/Sublime-Nit url = https://github.com/R4PaSs/Sublime-Nit
[submodule "vendor/grammars/language-hy"]
path = vendor/grammars/language-hy
url = https://github.com/rwtolbert/language-hy
[submodule "vendor/grammars/Racket"] [submodule "vendor/grammars/Racket"]
path = vendor/grammars/Racket path = vendor/grammars/Racket
url = https://github.com/soegaard/racket-highlight-for-github url = https://github.com/soegaard/racket-highlight-for-github
@@ -629,9 +614,6 @@
[submodule "vendor/grammars/language-yang"] [submodule "vendor/grammars/language-yang"]
path = vendor/grammars/language-yang path = vendor/grammars/language-yang
url = https://github.com/DzonyKalafut/language-yang.git url = https://github.com/DzonyKalafut/language-yang.git
[submodule "vendor/grammars/perl6fe"]
path = vendor/grammars/perl6fe
url = https://github.com/MadcapJake/language-perl6fe.git
[submodule "vendor/grammars/language-less"] [submodule "vendor/grammars/language-less"]
path = vendor/grammars/language-less path = vendor/grammars/language-less
url = https://github.com/atom/language-less.git url = https://github.com/atom/language-less.git
@@ -776,9 +758,6 @@
[submodule "vendor/grammars/vhdl"] [submodule "vendor/grammars/vhdl"]
path = vendor/grammars/vhdl path = vendor/grammars/vhdl
url = https://github.com/textmate/vhdl.tmbundle url = https://github.com/textmate/vhdl.tmbundle
[submodule "vendor/grammars/xquery"]
path = vendor/grammars/xquery
url = https://github.com/textmate/xquery.tmbundle
[submodule "vendor/grammars/language-rpm-spec"] [submodule "vendor/grammars/language-rpm-spec"]
path = vendor/grammars/language-rpm-spec path = vendor/grammars/language-rpm-spec
url = https://github.com/waveclaw/language-rpm-spec url = https://github.com/waveclaw/language-rpm-spec
@@ -797,3 +776,45 @@
[submodule "vendor/grammars/actionscript3-tmbundle"] [submodule "vendor/grammars/actionscript3-tmbundle"]
path = vendor/grammars/actionscript3-tmbundle path = vendor/grammars/actionscript3-tmbundle
url = https://github.com/simongregory/actionscript3-tmbundle url = https://github.com/simongregory/actionscript3-tmbundle
[submodule "vendor/grammars/ABNF.tmbundle"]
path = vendor/grammars/ABNF.tmbundle
url = https://github.com/sanssecours/ABNF.tmbundle
[submodule "vendor/grammars/EBNF.tmbundle"]
path = vendor/grammars/EBNF.tmbundle
url = https://github.com/sanssecours/EBNF.tmbundle
[submodule "vendor/grammars/language-haml"]
path = vendor/grammars/language-haml
url = https://github.com/ezekg/language-haml
[submodule "vendor/grammars/language-ninja"]
path = vendor/grammars/language-ninja
url = https://github.com/khyo/language-ninja
[submodule "vendor/grammars/language-fontforge"]
path = vendor/grammars/language-fontforge
url = https://github.com/Alhadis/language-fontforge
[submodule "vendor/grammars/language-gn"]
path = vendor/grammars/language-gn
url = https://github.com/devoncarew/language-gn
[submodule "vendor/grammars/rascal-syntax-highlighting"]
path = vendor/grammars/rascal-syntax-highlighting
url = https://github.com/usethesource/rascal-syntax-highlighting
[submodule "vendor/grammars/atom-language-perl6"]
path = vendor/grammars/atom-language-perl6
url = https://github.com/perl6/atom-language-perl6
[submodule "vendor/grammars/reason"]
path = vendor/grammars/reason
url = https://github.com/facebook/reason
[submodule "vendor/grammars/language-xcompose"]
path = vendor/grammars/language-xcompose
url = https://github.com/samcv/language-xcompose
[submodule "vendor/grammars/SublimeEthereum"]
path = vendor/grammars/SublimeEthereum
url = https://github.com/davidhq/SublimeEthereum.git
[submodule "vendor/grammars/atom-language-rust"]
path = vendor/grammars/atom-language-rust
url = https://github.com/zargony/atom-language-rust
[submodule "vendor/grammars/language-css"]
path = vendor/grammars/language-css
url = https://github.com/atom/language-css
[submodule "vendor/grammars/language-regexp"]
path = vendor/grammars/language-regexp
url = https://github.com/Alhadis/language-regexp

View File

@@ -17,7 +17,7 @@ To add support for a new extension:
In addition, if this extension is already listed in [`languages.yml`][languages] then sometimes a few more steps will need to be taken: In addition, if this extension is already listed in [`languages.yml`][languages] then sometimes a few more steps will need to be taken:
0. Make sure that example `.yourextension` files are present in the [samples directory][samples] for each language that uses `.yourextension`. 0. Make sure that example `.yourextension` files are present in the [samples directory][samples] for each language that uses `.yourextension`.
0. Test the performance of the Bayesian classifier with a relatively large number (1000s) of sample `.yourextension` files. (ping **@arfon** or **@bkeepers** to help with this) to ensure we're not misclassifying files. 0. Test the performance of the Bayesian classifier with a relatively large number (1000s) of sample `.yourextension` files. (ping **@bkeepers** to help with this) to ensure we're not misclassifying files.
0. If the Bayesian classifier does a bad job with the sample `.yourextension` files then a [heuristic](https://github.com/github/linguist/blob/master/lib/linguist/heuristics.rb) may need to be written to help. 0. If the Bayesian classifier does a bad job with the sample `.yourextension` files then a [heuristic](https://github.com/github/linguist/blob/master/lib/linguist/heuristics.rb) may need to be written to help.
@@ -36,7 +36,7 @@ To add support for a new language:
In addition, if your new language defines an extension that's already listed in [`languages.yml`][languages] (such as `.foo`) then sometimes a few more steps will need to be taken: In addition, if your new language defines an extension that's already listed in [`languages.yml`][languages] (such as `.foo`) then sometimes a few more steps will need to be taken:
0. Make sure that example `.foo` files are present in the [samples directory][samples] for each language that uses `.foo`. 0. Make sure that example `.foo` files are present in the [samples directory][samples] for each language that uses `.foo`.
0. Test the performance of the Bayesian classifier with a relatively large number (1000s) of sample `.foo` files. (ping **@arfon** or **@bkeepers** to help with this) to ensure we're not misclassifying files. 0. Test the performance of the Bayesian classifier with a relatively large number (1000s) of sample `.foo` files. (ping **@bkeepers** to help with this) to ensure we're not misclassifying files.
0. If the Bayesian classifier does a bad job with the sample `.foo` files then a [heuristic](https://github.com/github/linguist/blob/master/lib/linguist/heuristics.rb) may need to be written to help. 0. If the Bayesian classifier does a bad job with the sample `.foo` files then a [heuristic](https://github.com/github/linguist/blob/master/lib/linguist/heuristics.rb) may need to be written to help.
Remember, the goal here is to try and avoid false positives! Remember, the goal here is to try and avoid false positives!
@@ -79,8 +79,12 @@ Here's our current build status: [![Build Status](https://api.travis-ci.org/gith
Linguist is maintained with :heart: by: Linguist is maintained with :heart: by:
- **@arfon** (GitHub Staff) - **@Alhadis**
- **@brandonblack** (GitHub staff)
- **@larsbrinkhoff** - **@larsbrinkhoff**
- **@lildude** (GitHub staff)
- **@lizzhale** (GitHub staff)
- **@mikemcquaid** (GitHub staff)
- **@pchaigno** - **@pchaigno**
As Linguist is a production dependency for GitHub we have a couple of workflow restrictions: As Linguist is a production dependency for GitHub we have a couple of workflow restrictions:

View File

@@ -1,4 +1,4 @@
Copyright (c) 2011-2016 GitHub, Inc. Copyright (c) 2017 GitHub, Inc.
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation

View File

@@ -20,6 +20,12 @@ The Language stats bar displays languages percentages for the files in the repos
0. If the files are being misclassified, search for [open issues][issues] to see if anyone else has already reported the issue. Any information you can add, especially links to public repositories, is helpful. 0. If the files are being misclassified, search for [open issues][issues] to see if anyone else has already reported the issue. Any information you can add, especially links to public repositories, is helpful.
0. If there are no reported issues of this misclassification, [open an issue][new-issue] and include a link to the repository or a sample of the code that is being misclassified. 0. If there are no reported issues of this misclassification, [open an issue][new-issue] and include a link to the repository or a sample of the code that is being misclassified.
### There's a problem with the syntax highlighting of a file
Linguist detects the language of a file but the actual syntax-highlighting is powered by a set of language grammars which are included in this project as a set of submodules [and may be found here](https://github.com/github/linguist/blob/master/vendor/README.md).
If you experience an issue with the syntax-highlighting on GitHub, **please report the issue to the upstream grammar repository, not here.** Grammars are updated every time we build the Linguist gem and so upstream bug fixes are automatically incorporated as they are fixed.
## Overrides ## Overrides
Linguist supports a number of different custom overrides strategies for language definitions and vendored paths. Linguist supports a number of different custom overrides strategies for language definitions and vendored paths.

View File

@@ -1,5 +1,7 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
$LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
require 'linguist' require 'linguist'
require 'rugged' require 'rugged'
require 'optparse' require 'optparse'
@@ -102,10 +104,16 @@ def git_linguist(args)
commit = nil commit = nil
parser = OptionParser.new do |opts| parser = OptionParser.new do |opts|
opts.banner = "Usage: git-linguist [OPTIONS] stats|breakdown|dump-cache|clear|disable" opts.banner = <<-HELP
Linguist v#{Linguist::VERSION}
Detect language type and determine language breakdown for a given Git repository.
Usage:
git-linguist [OPTIONS] stats|breakdown|dump-cache|clear|disable"
HELP
opts.on("-f", "--force", "Force a full rescan") { incremental = false } opts.on("-f", "--force", "Force a full rescan") { incremental = false }
opts.on("--commit=COMMIT", "Commit to index") { |v| commit = v} opts.on("-c", "--commit=COMMIT", "Commit to index") { |v| commit = v}
end end
parser.parse!(args) parser.parse!(args)

View File

@@ -1,29 +1,37 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# linguist — detect language type for a file, or, given a directory, determine language breakdown $LOAD_PATH[0, 0] = File.join(File.dirname(__FILE__), '..', 'lib')
# usage: linguist <path> [<--breakdown>]
#
require 'linguist' require 'linguist'
require 'rugged' require 'rugged'
require 'json'
require 'optparse'
path = ARGV[0] || Dir.pwd path = ARGV[0] || Dir.pwd
# special case if not given a directory but still given the --breakdown option # special case if not given a directory
# but still given the --breakdown or --json options/
if path == "--breakdown" if path == "--breakdown"
path = Dir.pwd path = Dir.pwd
breakdown = true breakdown = true
elsif path == "--json"
path = Dir.pwd
json_breakdown = true
end end
ARGV.shift ARGV.shift
breakdown = true if ARGV[0] == "--breakdown" breakdown = true if ARGV[0] == "--breakdown"
json_breakdown = true if ARGV[0] == "--json"
if File.directory?(path) if File.directory?(path)
rugged = Rugged::Repository.new(path) rugged = Rugged::Repository.new(path)
repo = Linguist::Repository.new(rugged, rugged.head.target_id) repo = Linguist::Repository.new(rugged, rugged.head.target_id)
repo.languages.sort_by { |_, size| size }.reverse.each do |language, size| if !json_breakdown
percentage = ((size / repo.size.to_f) * 100) repo.languages.sort_by { |_, size| size }.reverse.each do |language, size|
percentage = sprintf '%.2f' % percentage percentage = ((size / repo.size.to_f) * 100)
puts "%-7s %s" % ["#{percentage}%", language] percentage = sprintf '%.2f' % percentage
puts "%-7s %s" % ["#{percentage}%", language]
end
end end
if breakdown if breakdown
puts puts
@@ -35,6 +43,8 @@ if File.directory?(path)
end end
puts puts
end end
elsif json_breakdown
puts JSON.dump(repo.breakdown_by_file)
end end
elsif File.file?(path) elsif File.file?(path)
blob = Linguist::FileBlob.new(path, Dir.pwd) blob = Linguist::FileBlob.new(path, Dir.pwd)
@@ -63,5 +73,12 @@ elsif File.file?(path)
puts " appears to be a vendored file" puts " appears to be a vendored file"
end end
else else
abort "usage: linguist <path>" abort <<-HELP
Linguist v#{Linguist::VERSION}
Detect language type for a file, or, given a directory, determine language breakdown.
Usage: linguist <path>
linguist <path> [--breakdown] [--json]
linguist [--breakdown] [--json]
HELP
end end

View File

@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
s.add_dependency 'charlock_holmes', '~> 0.7.3' s.add_dependency 'charlock_holmes', '~> 0.7.3'
s.add_dependency 'escape_utils', '~> 1.1.0' s.add_dependency 'escape_utils', '~> 1.1.0'
s.add_dependency 'mime-types', '>= 1.19' s.add_dependency 'mime-types', '>= 1.19'
s.add_dependency 'rugged', '>= 0.23.0b' s.add_dependency 'rugged', '>= 0.25.1'
s.add_development_dependency 'minitest', '>= 5.0' s.add_development_dependency 'minitest', '>= 5.0'
s.add_development_dependency 'mocha' s.add_development_dependency 'mocha'
@@ -27,5 +27,4 @@ Gem::Specification.new do |s|
s.add_development_dependency 'color-proximity', '~> 0.2.1' s.add_development_dependency 'color-proximity', '~> 0.2.1'
s.add_development_dependency 'licensed' s.add_development_dependency 'licensed'
s.add_development_dependency 'licensee', '>= 8.6.0' s.add_development_dependency 'licensee', '>= 8.6.0'
end end

View File

@@ -1,9 +1,11 @@
--- ---
http://svn.edgewall.org/repos/genshi/contrib/textmate/Genshi.tmbundle/Syntaxes/Markup%20Template%20%28XML%29.tmLanguage:
- text.xml.genshi
https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz: https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz:
- source.systemverilog - source.systemverilog
- source.ucfconstraints - source.ucfconstraints
https://svn.edgewall.org/repos/genshi/contrib/textmate/Genshi.tmbundle/Syntaxes/Markup%20Template%20%28XML%29.tmLanguage:
- text.xml.genshi
vendor/grammars/ABNF.tmbundle:
- source.abnf
vendor/grammars/Agda.tmbundle: vendor/grammars/Agda.tmbundle:
- source.agda - source.agda
vendor/grammars/Alloy.tmbundle: vendor/grammars/Alloy.tmbundle:
@@ -20,6 +22,8 @@ vendor/grammars/ColdFusion:
- text.html.cfm - text.html.cfm
vendor/grammars/Docker.tmbundle: vendor/grammars/Docker.tmbundle:
- source.dockerfile - source.dockerfile
vendor/grammars/EBNF.tmbundle:
- source.ebnf
vendor/grammars/Elm/Syntaxes: vendor/grammars/Elm/Syntaxes:
- source.elm - source.elm
- text.html.mediawiki.elm-build-output - text.html.mediawiki.elm-build-output
@@ -109,7 +113,9 @@ vendor/grammars/SublimeBrainfuck:
- source.bf - source.bf
vendor/grammars/SublimeClarion: vendor/grammars/SublimeClarion:
- source.clarion - source.clarion
vendor/grammars/SublimeGDB: vendor/grammars/SublimeEthereum:
- source.solidity
vendor/grammars/SublimeGDB/:
- source.disasm - source.disasm
- source.gdb - source.gdb
- source.gdb.session - source.gdb.session
@@ -174,8 +180,15 @@ vendor/grammars/atom-language-1c-bsl:
- source.sdbl - source.sdbl
vendor/grammars/atom-language-clean: vendor/grammars/atom-language-clean:
- source.clean - source.clean
vendor/grammars/atom-language-perl6:
- source.meta-info
- source.perl6fe
- source.quoting.perl6fe
- source.regexp.perl6fe
vendor/grammars/atom-language-purescript: vendor/grammars/atom-language-purescript:
- source.purescript - source.purescript
vendor/grammars/atom-language-rust:
- source.rust
vendor/grammars/atom-language-srt: vendor/grammars/atom-language-srt:
- text.srt - text.srt
vendor/grammars/atom-language-stan: vendor/grammars/atom-language-stan:
@@ -221,8 +234,6 @@ vendor/grammars/cpp-qt.tmbundle:
- source.qmake - source.qmake
vendor/grammars/creole: vendor/grammars/creole:
- text.html.creole - text.html.creole
vendor/grammars/css.tmbundle:
- source.css
vendor/grammars/cucumber-tmbundle: vendor/grammars/cucumber-tmbundle:
- source.ruby.rspec.cucumber.steps - source.ruby.rspec.cucumber.steps
- text.gherkin.feature - text.gherkin.feature
@@ -356,12 +367,23 @@ vendor/grammars/language-csound:
- source.csound - source.csound
- source.csound-document - source.csound-document
- source.csound-score - source.csound-score
vendor/grammars/language-css:
- source.css
vendor/grammars/language-emacs-lisp: vendor/grammars/language-emacs-lisp:
- source.emacs.lisp - source.emacs.lisp
vendor/grammars/language-fontforge:
- source.fontforge
- source.opentype
- text.sfd
vendor/grammars/language-gfm: vendor/grammars/language-gfm:
- source.gfm - source.gfm
vendor/grammars/language-gn:
- source.gn
vendor/grammars/language-graphql: vendor/grammars/language-graphql:
- source.graphql - source.graphql
vendor/grammars/language-haml:
- text.haml
- text.hamlc
vendor/grammars/language-haskell: vendor/grammars/language-haskell:
- hint.haskell - hint.haskell
- hint.message.haskell - hint.message.haskell
@@ -371,13 +393,10 @@ vendor/grammars/language-haskell:
- source.haskell - source.haskell
- source.hsc2hs - source.hsc2hs
- text.tex.latex.haskell - text.tex.latex.haskell
vendor/grammars/language-hy:
- source.hy
vendor/grammars/language-inform7: vendor/grammars/language-inform7:
- source.inform7 - source.inform7
vendor/grammars/language-javascript: vendor/grammars/language-javascript:
- source.js - source.js
- source.js.embedded.html
- source.js.regexp - source.js.regexp
- source.js.regexp.replacement - source.js.regexp.replacement
vendor/grammars/language-jsoniq: vendor/grammars/language-jsoniq:
@@ -389,11 +408,17 @@ vendor/grammars/language-maxscript:
- source.maxscript - source.maxscript
vendor/grammars/language-ncl: vendor/grammars/language-ncl:
- source.ncl - source.ncl
vendor/grammars/language-ninja:
- source.ninja
vendor/grammars/language-povray: vendor/grammars/language-povray:
- source.pov-ray sdl - source.pov-ray sdl
vendor/grammars/language-python: vendor/grammars/language-python:
- text.python.console - text.python.console
- text.python.traceback - text.python.traceback
vendor/grammars/language-regexp:
- source.regexp
- source.regexp.comment
- source.regexp.extended
vendor/grammars/language-renpy: vendor/grammars/language-renpy:
- source.renpy - source.renpy
vendor/grammars/language-restructuredtext: vendor/grammars/language-restructuredtext:
@@ -422,6 +447,8 @@ vendor/grammars/language-wavefront:
- source.wavefront.obj - source.wavefront.obj
vendor/grammars/language-xbase: vendor/grammars/language-xbase:
- source.harbour - source.harbour
vendor/grammars/language-xcompose:
- config.xcompose
vendor/grammars/language-yaml: vendor/grammars/language-yaml:
- source.yaml - source.yaml
vendor/grammars/language-yang: vendor/grammars/language-yang:
@@ -470,8 +497,6 @@ vendor/grammars/nemerle.tmbundle:
- source.nemerle - source.nemerle
vendor/grammars/nesC: vendor/grammars/nesC:
- source.nesc - source.nesc
vendor/grammars/ninja.tmbundle:
- source.ninja
vendor/grammars/nix: vendor/grammars/nix:
- source.nix - source.nix
vendor/grammars/nu.tmbundle: vendor/grammars/nu.tmbundle:
@@ -501,10 +526,6 @@ vendor/grammars/pawn-sublime-language:
vendor/grammars/perl.tmbundle: vendor/grammars/perl.tmbundle:
- source.perl - source.perl
- source.perl.6 - source.perl.6
vendor/grammars/perl6fe:
- source.meta-info
- source.perl6fe
- source.regexp.perl6fe
vendor/grammars/php-smarty.tmbundle: vendor/grammars/php-smarty.tmbundle:
- text.html.smarty - text.html.smarty
vendor/grammars/php.tmbundle: vendor/grammars/php.tmbundle:
@@ -527,8 +548,10 @@ vendor/grammars/python-django.tmbundle:
vendor/grammars/r.tmbundle: vendor/grammars/r.tmbundle:
- source.r - source.r
- text.tex.latex.rd - text.tex.latex.rd
vendor/grammars/ruby-haml.tmbundle: vendor/grammars/rascal-syntax-highlighting:
- text.haml - source.rascal
vendor/grammars/reason:
- source.reason
vendor/grammars/ruby-slim.tmbundle: vendor/grammars/ruby-slim.tmbundle:
- text.slim - text.slim
vendor/grammars/ruby.tmbundle: vendor/grammars/ruby.tmbundle:
@@ -596,8 +619,6 @@ vendor/grammars/sublime-rexx:
- source.rexx - source.rexx
vendor/grammars/sublime-robot-plugin: vendor/grammars/sublime-robot-plugin:
- text.robot - text.robot
vendor/grammars/sublime-rust:
- source.rust
vendor/grammars/sublime-spintools: vendor/grammars/sublime-spintools:
- source.regexp.spin - source.regexp.spin
- source.spin - source.spin
@@ -649,7 +670,5 @@ vendor/grammars/xc.tmbundle:
vendor/grammars/xml.tmbundle: vendor/grammars/xml.tmbundle:
- text.xml - text.xml
- text.xml.xsl - text.xml.xsl
vendor/grammars/xquery:
- source.xquery
vendor/grammars/zephir-sublime: vendor/grammars/zephir-sublime:
- source.php.zephir - source.php.zephir

View File

@@ -59,8 +59,9 @@ class << Linguist
# Strategies are called in turn until a single Language is returned. # Strategies are called in turn until a single Language is returned.
STRATEGIES = [ STRATEGIES = [
Linguist::Strategy::Modeline, Linguist::Strategy::Modeline,
Linguist::Shebang,
Linguist::Strategy::Filename, Linguist::Strategy::Filename,
Linguist::Shebang,
Linguist::Strategy::Extension,
Linguist::Heuristics, Linguist::Heuristics,
Linguist::Classifier Linguist::Classifier
] ]

View File

@@ -63,7 +63,7 @@ module Linguist
# #
# Returns an Array # Returns an Array
def extensions def extensions
_, *segments = name.downcase.split(".") _, *segments = name.downcase.split(".", -1)
segments.map.with_index do |segment, index| segments.map.with_index do |segment, index|
"." + segments[index..-1].join(".") "." + segments[index..-1].join(".")

View File

@@ -95,7 +95,7 @@ module Linguist
# Returns sorted Array of result pairs. Each pair contains the # Returns sorted Array of result pairs. Each pair contains the
# String language name and a Float score. # String language name and a Float score.
def classify(tokens, languages) def classify(tokens, languages)
return [] if tokens.nil? return [] if tokens.nil? || languages.empty?
tokens = Tokenizer.tokenize(tokens) if tokens.is_a?(String) tokens = Tokenizer.tokenize(tokens) if tokens.is_a?(String)
scores = {} scores = {}

View File

@@ -3,7 +3,7 @@ module Linguist
# Public: Is the blob a generated file? # Public: Is the blob a generated file?
# #
# name - String filename # name - String filename
# data - String blob data. A block also maybe passed in for lazy # data - String blob data. A block also may be passed in for lazy
# loading. This behavior is deprecated and you should always # loading. This behavior is deprecated and you should always
# pass in a String. # pass in a String.
# #
@@ -56,6 +56,7 @@ module Linguist
generated_net_specflow_feature_file? || generated_net_specflow_feature_file? ||
composer_lock? || composer_lock? ||
node_modules? || node_modules? ||
go_vendor? ||
npm_shrinkwrap? || npm_shrinkwrap? ||
godeps? || godeps? ||
generated_by_zephir? || generated_by_zephir? ||
@@ -69,6 +70,7 @@ module Linguist
compiled_cython_file? || compiled_cython_file? ||
generated_go? || generated_go? ||
generated_protocol_buffer? || generated_protocol_buffer? ||
generated_javascript_protocol_buffer? ||
generated_apache_thrift? || generated_apache_thrift? ||
generated_jni_header? || generated_jni_header? ||
vcr_cassette? || vcr_cassette? ||
@@ -76,7 +78,10 @@ module Linguist
generated_unity3d_meta? || generated_unity3d_meta? ||
generated_racc? || generated_racc? ||
generated_jflex? || generated_jflex? ||
generated_grammarkit? generated_grammarkit? ||
generated_roxygen2? ||
generated_jison? ||
generated_yarn_lock?
end end
# Internal: Is the blob an Xcode file? # Internal: Is the blob an Xcode file?
@@ -274,16 +279,25 @@ module Linguist
return lines[0].include?("Generated by the protocol buffer compiler. DO NOT EDIT!") return lines[0].include?("Generated by the protocol buffer compiler. DO NOT EDIT!")
end end
APACHE_THRIFT_EXTENSIONS = ['.rb', '.py', '.go', '.js', '.m', '.java', '.h', '.cc', '.cpp'] # Internal: Is the blob a Javascript source file generated by the
# Protocol Buffer compiler?
#
# Returns true of false.
def generated_javascript_protocol_buffer?
return false unless extname == ".js"
return false unless lines.count > 6
return lines[5].include?("GENERATED CODE -- DO NOT EDIT!")
end
APACHE_THRIFT_EXTENSIONS = ['.rb', '.py', '.go', '.js', '.m', '.java', '.h', '.cc', '.cpp', '.php']
# Internal: Is the blob generated by Apache Thrift compiler? # Internal: Is the blob generated by Apache Thrift compiler?
# #
# Returns true or false # Returns true or false
def generated_apache_thrift? def generated_apache_thrift?
return false unless APACHE_THRIFT_EXTENSIONS.include?(extname) return false unless APACHE_THRIFT_EXTENSIONS.include?(extname)
return false unless lines.count > 1 return lines.first(6).any? { |l| l.include?("Autogenerated by Thrift Compiler") }
return lines[0].include?("Autogenerated by Thrift Compiler") || lines[1].include?("Autogenerated by Thrift Compiler")
end end
# Internal: Is the blob a C/C++ header generated by the Java JNI tool javah? # Internal: Is the blob a C/C++ header generated by the Java JNI tool javah?
@@ -304,7 +318,15 @@ module Linguist
!!name.match(/node_modules\//) !!name.match(/node_modules\//)
end end
# Internal: Is the blob a generated npm shrinkwrap file. # Internal: Is the blob part of the Go vendor/ tree,
# not meant for humans in pull requests.
#
# Returns true or false.
def go_vendor?
!!name.match(/vendor\/((?!-)[-0-9A-Za-z]+(?<!-)\.)+(com|edu|gov|in|me|net|org|fm|io)/)
end
# Internal: Is the blob a generated npm shrinkwrap file?
# #
# Returns true or false. # Returns true or false.
def npm_shrinkwrap? def npm_shrinkwrap?
@@ -326,7 +348,7 @@ module Linguist
!!name.match(/composer\.lock/) !!name.match(/composer\.lock/)
end end
# Internal: Is the blob a generated by Zephir # Internal: Is the blob generated by Zephir?
# #
# Returns true or false. # Returns true or false.
def generated_by_zephir? def generated_by_zephir?
@@ -426,5 +448,46 @@ module Linguist
return false unless lines.count > 1 return false unless lines.count > 1
return lines[0].start_with?("// This is a generated file. Not intended for manual editing.") return lines[0].start_with?("// This is a generated file. Not intended for manual editing.")
end end
# Internal: Is this a roxygen2-generated file?
#
# A roxygen2-generated file typically contain:
# % Generated by roxygen2: do not edit by hand
# on the first line.
#
# Return true or false
def generated_roxygen2?
return false unless extname == '.Rd'
return false unless lines.count > 1
return lines[0].include?("% Generated by roxygen2: do not edit by hand")
end
# Internal: Is this a Jison-generated file?
#
# Jison-generated parsers typically contain:
# /* parser generated by jison
# on the first line.
#
# Jison-generated lexers typically contain:
# /* generated by jison-lex
# on the first line.
#
# Return true or false
def generated_jison?
return false unless extname == '.js'
return false unless lines.count > 1
return lines[0].start_with?("/* parser generated by jison ") ||
lines[0].start_with?("/* generated by jison-lex ")
end
# Internal: Is the blob a generated yarn lockfile?
#
# Returns true or false.
def generated_yarn_lock?
return false unless name.match(/yarn\.lock/)
return false unless lines.count > 0
return lines[0].include?("# THIS IS AN AUTOGENERATED FILE")
end
end end
end end

View File

@@ -110,6 +110,12 @@ module Linguist
end end
end end
disambiguate ".cls" do |data|
if /\\\w+{/.match(data)
Language["TeX"]
end
end
disambiguate ".cs" do |data| disambiguate ".cs" do |data|
if /![\w\s]+methodsFor: /.match(data) if /![\w\s]+methodsFor: /.match(data)
Language["Smalltalk"] Language["Smalltalk"]
@@ -254,7 +260,7 @@ module Linguist
end end
disambiguate ".md" do |data| disambiguate ".md" do |data|
if /(^[-a-z0-9=#!\*\[|])|<\//i.match(data) || data.empty? if /(^[-a-z0-9=#!\*\[|>])|<\//i.match(data) || data.empty?
Language["Markdown"] Language["Markdown"]
elsif /^(;;|\(define_)/.match(data) elsif /^(;;|\(define_)/.match(data)
Language["GCC machine description"] Language["GCC machine description"]
@@ -272,7 +278,7 @@ module Linguist
disambiguate ".mod" do |data| disambiguate ".mod" do |data|
if data.include?('<!ENTITY ') if data.include?('<!ENTITY ')
Language["XML"] Language["XML"]
elsif /MODULE\s\w+\s*;/i.match(data) || /^\s*END \w+;$/i.match(data) elsif /^\s*MODULE [\w\.]+;/i.match(data) || /^\s*END [\w\.]+;/i.match(data)
Language["Modula-2"] Language["Modula-2"]
else else
[Language["Linux Kernel Module"], Language["AMPL"]] [Language["Linux Kernel Module"], Language["AMPL"]]
@@ -320,7 +326,7 @@ module Linguist
end end
disambiguate ".pl" do |data| disambiguate ".pl" do |data|
if /^[^#]+:-/.match(data) if /^[^#]*:-/.match(data)
Language["Prolog"] Language["Prolog"]
elsif /use strict|use\s+v?5\./.match(data) elsif /use strict|use\s+v?5\./.match(data)
Language["Perl"] Language["Perl"]

View File

@@ -11,6 +11,7 @@ require 'linguist/samples'
require 'linguist/file_blob' require 'linguist/file_blob'
require 'linguist/blob_helper' require 'linguist/blob_helper'
require 'linguist/strategy/filename' require 'linguist/strategy/filename'
require 'linguist/strategy/extension'
require 'linguist/strategy/modeline' require 'linguist/strategy/modeline'
require 'linguist/shebang' require 'linguist/shebang'
@@ -90,17 +91,6 @@ module Linguist
language language
end end
# Public: Detects the Language of the blob.
#
# blob - an object that includes the Linguist `BlobHelper` interface;
# see Linguist::LazyBlob and Linguist::FileBlob for examples
#
# Returns Language or nil.
def self.detect(blob)
warn "[DEPRECATED] `Linguist::Language.detect` is deprecated. Use `Linguist.detect`. #{caller[0]}"
Linguist.detect(blob)
end
# Public: Get all Languages # Public: Get all Languages
# #
# Returns an Array of Languages # Returns an Array of Languages
@@ -140,46 +130,46 @@ module Linguist
# Public: Look up Languages by filename. # Public: Look up Languages by filename.
# #
# The behaviour of this method recently changed.
# See the second example below.
#
# filename - The path String. # filename - The path String.
# #
# Examples # Examples
# #
# Language.find_by_filename('Cakefile')
# # => [#<Language name="CoffeeScript">]
# Language.find_by_filename('foo.rb') # Language.find_by_filename('foo.rb')
# # => [#<Language name="Ruby">] # # => []
# #
# Returns all matching Languages or [] if none were found. # Returns all matching Languages or [] if none were found.
def self.find_by_filename(filename) def self.find_by_filename(filename)
basename = File.basename(filename) basename = File.basename(filename)
@filename_index[basename]
# find the first extension with language definitions
extname = FileBlob.new(filename).extensions.detect do |e|
!@extension_index[e].empty?
end
(@filename_index[basename] + @extension_index[extname]).compact.uniq
end end
# Public: Look up Languages by file extension. # Public: Look up Languages by file extension.
# #
# extname - The extension String. # The behaviour of this method recently changed.
# See the second example below.
#
# filename - The path String.
# #
# Examples # Examples
# #
# Language.find_by_extension('.rb') # Language.find_by_extension('dummy.rb')
# # => [#<Language name="Ruby">] # # => [#<Language name="Ruby">]
#
# Language.find_by_extension('rb') # Language.find_by_extension('rb')
# # => [#<Language name="Ruby">] # # => []
# #
# Returns all matching Languages or [] if none were found. # Returns all matching Languages or [] if none were found.
def self.find_by_extension(extname) def self.find_by_extension(filename)
extname = ".#{extname}" unless extname.start_with?(".") # find the first extension with language definitions
@extension_index[extname.downcase] extname = FileBlob.new(filename.downcase).extensions.detect do |e|
end !@extension_index[e].empty?
end
# DEPRECATED @extension_index[extname]
def self.find_by_shebang(data)
@interpreter_index[Shebang.interpreter(data)]
end end
# Public: Look up Languages by interpreter. # Public: Look up Languages by interpreter.
@@ -225,7 +215,14 @@ module Linguist
# Returns the Language or nil if none was found. # Returns the Language or nil if none was found.
def self.[](name) def self.[](name)
return nil if name.to_s.empty? return nil if name.to_s.empty?
name && (@index[name.downcase] || @index[name.split(',').first.downcase])
lang = @index[name.downcase]
return lang if lang
name = name.split(',').first
return nil if name.to_s.empty?
@index[name.downcase]
end end
# Public: A List of popular languages # Public: A List of popular languages
@@ -259,18 +256,6 @@ module Linguist
@colors ||= all.select(&:color).sort_by { |lang| lang.name.downcase } @colors ||= all.select(&:color).sort_by { |lang| lang.name.downcase }
end end
# Public: A List of languages compatible with Ace.
#
# TODO: Remove this method in a 5.x release. Every language now needs an ace_mode
# key, so this function isn't doing anything unique anymore.
#
# Returns an Array of Languages.
def self.ace_modes
warn "This method will be deprecated in a future 5.x release. Every language now has an `ace_mode` set."
warn caller
@ace_modes ||= all.select(&:ace_mode).sort_by { |lang| lang.name.downcase }
end
# Internal: Initialize a new Language # Internal: Initialize a new Language
# #
# attributes - A hash of attributes # attributes - A hash of attributes
@@ -287,7 +272,7 @@ module Linguist
@color = attributes[:color] @color = attributes[:color]
# Set aliases # Set aliases
@aliases = [default_alias_name] + (attributes[:aliases] || []) @aliases = [default_alias] + (attributes[:aliases] || [])
# Load the TextMate scope name or try to guess one # Load the TextMate scope name or try to guess one
@tm_scope = attributes[:tm_scope] || begin @tm_scope = attributes[:tm_scope] || begin
@@ -305,9 +290,6 @@ module Linguist
@codemirror_mime_type = attributes[:codemirror_mime_type] @codemirror_mime_type = attributes[:codemirror_mime_type]
@wrap = attributes[:wrap] || false @wrap = attributes[:wrap] || false
# Set legacy search term
@search_term = attributes[:search_term] || default_alias_name
# Set the language_id # Set the language_id
@language_id = attributes[:language_id] @language_id = attributes[:language_id]
@@ -362,17 +344,6 @@ module Linguist
# Returns an Array of String names # Returns an Array of String names
attr_reader :aliases attr_reader :aliases
# Deprecated: Get code search term
#
# Examples
#
# # => "ruby"
# # => "python"
# # => "perl"
#
# Returns the name String
attr_reader :search_term
# Public: Get language_id (used in GitHub search) # Public: Get language_id (used in GitHub search)
# #
# Examples # Examples
@@ -457,22 +428,6 @@ module Linguist
# Returns the extensions Array # Returns the extensions Array
attr_reader :filenames attr_reader :filenames
# Deprecated: Get primary extension
#
# Defaults to the first extension but can be overridden
# in the languages.yml.
#
# The primary extension can not be nil. Tests should verify this.
#
# This method is only used by app/helpers/gists_helper.rb for creating
# the language dropdown. It really should be using `name` instead.
# Would like to drop primary extension.
#
# Returns the extension String.
def primary_extension
extensions.first
end
# Public: Get URL escaped name. # Public: Get URL escaped name.
# #
# Examples # Examples
@@ -486,12 +441,13 @@ module Linguist
EscapeUtils.escape_url(name).gsub('+', '%20') EscapeUtils.escape_url(name).gsub('+', '%20')
end end
# Internal: Get default alias name # Public: Get default alias name
# #
# Returns the alias name String # Returns the alias name String
def default_alias_name def default_alias
name.downcase.gsub(/\s/, '-') name.downcase.gsub(/\s/, '-')
end end
alias_method :default_alias_name, :default_alias
# Public: Get Language group # Public: Get Language group
# #
@@ -606,7 +562,6 @@ module Linguist
:wrap => options['wrap'], :wrap => options['wrap'],
:group_name => options['group'], :group_name => options['group'],
:searchable => options.fetch('searchable', true), :searchable => options.fetch('searchable', true),
:search_term => options['search_term'],
:language_id => options['language_id'], :language_id => options['language_id'],
:extensions => Array(options['extensions']), :extensions => Array(options['extensions']),
:interpreters => options['interpreters'].sort, :interpreters => options['interpreters'].sort,

View File

@@ -14,12 +14,10 @@
# listed alphabetically) # listed alphabetically)
# interpreters - An Array of associated interpreters # interpreters - An Array of associated interpreters
# searchable - Boolean flag to enable searching (defaults to true) # searchable - Boolean flag to enable searching (defaults to true)
# search_term - Deprecated: Some languages may be indexed under a
# different alias. Avoid defining new exceptions.
# language_id - Integer used as a language-name-independent indexed field so that we can rename # language_id - Integer used as a language-name-independent indexed field so that we can rename
# languages in Linguist without reindexing all the code on GitHub. Must not be # languages in Linguist without reindexing all the code on GitHub. Must not be
# changed for existing languages without the explicit permission of GitHub staff. # changed for existing languages without the explicit permission of GitHub staff.
# color - CSS hex color to represent the language. Only used if type is "programming" or "prose" # color - CSS hex color to represent the language. Only used if type is "programming" or "prose".
# tm_scope - The TextMate scope that represents this programming # tm_scope - The TextMate scope that represents this programming
# language. This should match one of the scopes listed in # language. This should match one of the scopes listed in
# the grammars.yml file. Use "none" if there is no grammar # the grammars.yml file. Use "none" if there is no grammar
@@ -49,6 +47,13 @@ ABAP:
- ".abap" - ".abap"
ace_mode: abap ace_mode: abap
language_id: 1 language_id: 1
ABNF:
type: data
ace_mode: text
extensions:
- ".abnf"
tm_scope: source.abnf
language_id: 429
AGS Script: AGS Script:
type: programming type: programming
color: "#B9D9FF" color: "#B9D9FF"
@@ -114,7 +119,6 @@ ASN.1:
ASP: ASP:
type: programming type: programming
color: "#6a40fd" color: "#6a40fd"
search_term: aspx-vb
tm_scope: text.html.asp tm_scope: text.html.asp
aliases: aliases:
- aspx - aspx
@@ -147,7 +151,6 @@ ActionScript:
type: programming type: programming
tm_scope: source.actionscript.3 tm_scope: source.actionscript.3
color: "#882B0F" color: "#882B0F"
search_term: as3
aliases: aliases:
- actionscript 3 - actionscript 3
- actionscript3 - actionscript3
@@ -284,7 +287,6 @@ AspectJ:
Assembly: Assembly:
type: programming type: programming
color: "#6E4C13" color: "#6E4C13"
search_term: nasm
aliases: aliases:
- nasm - nasm
extensions: extensions:
@@ -342,7 +344,6 @@ Awk:
language_id: 28 language_id: 28
Batchfile: Batchfile:
type: programming type: programming
search_term: bat
aliases: aliases:
- bat - bat
- batch - batch
@@ -467,7 +468,6 @@ C#:
codemirror_mode: clike codemirror_mode: clike
codemirror_mime_type: text/x-csharp codemirror_mime_type: text/x-csharp
tm_scope: source.cs tm_scope: source.cs
search_term: csharp
color: "#178600" color: "#178600"
aliases: aliases:
- csharp - csharp
@@ -482,7 +482,6 @@ C++:
ace_mode: c_cpp ace_mode: c_cpp
codemirror_mode: clike codemirror_mode: clike
codemirror_mime_type: text/x-c++src codemirror_mime_type: text/x-c++src
search_term: cpp
color: "#f34b7d" color: "#f34b7d"
aliases: aliases:
- cpp - cpp
@@ -500,6 +499,7 @@ C++:
- ".inc" - ".inc"
- ".inl" - ".inl"
- ".ipp" - ".ipp"
- ".re"
- ".tcc" - ".tcc"
- ".tpp" - ".tpp"
language_id: 43 language_id: 43
@@ -712,7 +712,6 @@ ColdFusion:
type: programming type: programming
ace_mode: coldfusion ace_mode: coldfusion
color: "#ed2cd6" color: "#ed2cd6"
search_term: cfm
aliases: aliases:
- cfm - cfm
- cfml - cfml
@@ -726,7 +725,6 @@ ColdFusion CFC:
type: programming type: programming
group: ColdFusion group: ColdFusion
ace_mode: coldfusion ace_mode: coldfusion
search_term: cfc
aliases: aliases:
- cfc - cfc
extensions: extensions:
@@ -847,16 +845,6 @@ Csound Score:
tm_scope: source.csound-score tm_scope: source.csound-score
ace_mode: text ace_mode: text
language_id: 75 language_id: 75
Cucumber:
type: programming
extensions:
- ".feature"
tm_scope: text.gherkin.feature
aliases:
- gherkin
ace_mode: text
color: "#5B2063"
language_id: 76
Cuda: Cuda:
type: programming type: programming
extensions: extensions:
@@ -949,7 +937,6 @@ DTrace:
language_id: 85 language_id: 85
Darcs Patch: Darcs Patch:
type: data type: data
search_term: dpatch
aliases: aliases:
- dpatch - dpatch
extensions: extensions:
@@ -1022,6 +1009,15 @@ E:
tm_scope: none tm_scope: none
ace_mode: text ace_mode: text
language_id: 92 language_id: 92
EBNF:
type: data
extensions:
- ".ebnf"
tm_scope: source.ebnf
ace_mode: text
codemirror_mode: ebnf
codemirror_mime_type: text/x-ebnf
language_id: 430
ECL: ECL:
type: programming type: programming
color: "#8a1267" color: "#8a1267"
@@ -1125,9 +1121,10 @@ Emacs Lisp:
- ".gnus" - ".gnus"
- ".spacemacs" - ".spacemacs"
- ".viper" - ".viper"
- "Project.ede" - Cask
- "_emacs" - Project.ede
- "abbrev_defs" - _emacs
- abbrev_defs
extensions: extensions:
- ".el" - ".el"
- ".emacs" - ".emacs"
@@ -1159,6 +1156,7 @@ Erlang:
- ".xrl" - ".xrl"
- ".yrl" - ".yrl"
filenames: filenames:
- Emakefile
- rebar.config - rebar.config
- rebar.config.lock - rebar.config.lock
- rebar.lock - rebar.lock
@@ -1171,7 +1169,6 @@ Erlang:
F#: F#:
type: programming type: programming
color: "#b845fc" color: "#b845fc"
search_term: fsharp
aliases: aliases:
- fsharp - fsharp
extensions: extensions:
@@ -1192,23 +1189,6 @@ FLUX:
tm_scope: none tm_scope: none
ace_mode: text ace_mode: text
language_id: 106 language_id: 106
FORTRAN:
type: programming
color: "#4d41b1"
extensions:
- ".f90"
- ".f"
- ".f03"
- ".f08"
- ".f77"
- ".f95"
- ".for"
- ".fpp"
tm_scope: source.fortran.modern
ace_mode: text
codemirror_mode: fortran
codemirror_mime_type: text/x-fortran
language_id: 107
Factor: Factor:
type: programming type: programming
color: "#636746" color: "#636746"
@@ -1278,6 +1258,23 @@ Forth:
codemirror_mode: forth codemirror_mode: forth
codemirror_mime_type: text/x-forth codemirror_mime_type: text/x-forth
language_id: 114 language_id: 114
Fortran:
type: programming
color: "#4d41b1"
extensions:
- ".f90"
- ".f"
- ".f03"
- ".f08"
- ".f77"
- ".f95"
- ".for"
- ".fpp"
tm_scope: source.fortran.modern
ace_mode: text
codemirror_mode: fortran
codemirror_mime_type: text/x-fortran
language_id: 107
FreeMarker: FreeMarker:
type: programming type: programming
color: "#0050b2" color: "#0050b2"
@@ -1323,15 +1320,6 @@ GAP:
tm_scope: source.gap tm_scope: source.gap
ace_mode: text ace_mode: text
language_id: 119 language_id: 119
GAS:
type: programming
group: Assembly
extensions:
- ".s"
- ".ms"
tm_scope: source.assembly
ace_mode: assembly_x86
language_id: 120
GCC Machine Description: GCC Machine Description:
type: programming type: programming
extensions: extensions:
@@ -1377,6 +1365,18 @@ GLSL:
- ".vshader" - ".vshader"
ace_mode: glsl ace_mode: glsl
language_id: 124 language_id: 124
GN:
type: data
extensions:
- ".gn"
- ".gni"
interpreters:
- gn
tm_scope: source.gn
ace_mode: python
codemirror_mode: python
codemirror_mime_type: text/x-python
language_id: 302957008
Game Maker Language: Game Maker Language:
type: programming type: programming
color: "#8fb200" color: "#8fb200"
@@ -1387,6 +1387,14 @@ Game Maker Language:
codemirror_mode: clike codemirror_mode: clike
codemirror_mime_type: text/x-c++src codemirror_mime_type: text/x-c++src
language_id: 125 language_id: 125
Genie:
type: programming
ace_mode: text
extensions:
- ".gs"
color: "#fb855d"
tm_scope: none
language_id: 792408528
Genshi: Genshi:
type: programming type: programming
extensions: extensions:
@@ -1421,7 +1429,6 @@ Gentoo Eclass:
language_id: 128 language_id: 128
Gettext Catalog: Gettext Catalog:
type: prose type: prose
search_term: pot
searchable: false searchable: false
aliases: aliases:
- pot - pot
@@ -1431,6 +1438,16 @@ Gettext Catalog:
tm_scope: source.po tm_scope: source.po
ace_mode: text ace_mode: text
language_id: 129 language_id: 129
Gherkin:
type: programming
extensions:
- ".feature"
tm_scope: text.gherkin.feature
aliases:
- cucumber
ace_mode: text
color: "#5B2063"
language_id: 76
Glyph: Glyph:
type: programming type: programming
color: "#e4cc98" color: "#e4cc98"
@@ -1457,6 +1474,8 @@ Gnuplot:
Go: Go:
type: programming type: programming
color: "#375eab" color: "#375eab"
aliases:
- golang
extensions: extensions:
- ".go" - ".go"
ace_mode: golang ace_mode: golang
@@ -1532,45 +1551,6 @@ Graphviz (DOT):
- ".gv" - ".gv"
ace_mode: text ace_mode: text
language_id: 140 language_id: 140
Groff:
type: markup
color: "#ecdebe"
extensions:
- ".man"
- ".1"
- ".1in"
- ".1m"
- ".1x"
- ".2"
- ".3"
- ".3in"
- ".3m"
- ".3qt"
- ".3x"
- ".4"
- ".5"
- ".6"
- ".7"
- ".8"
- ".9"
- ".l"
- ".me"
- ".ms"
- ".n"
- ".rno"
- ".roff"
- ".tmac"
filenames:
- mmn
- mmt
tm_scope: text.roff
aliases:
- nroff
- troff
ace_mode: text
codemirror_mode: troff
codemirror_mime_type: text/troff
language_id: 141
Groovy: Groovy:
type: programming type: programming
ace_mode: groovy ace_mode: groovy
@@ -1626,7 +1606,7 @@ HTML:
ace_mode: html ace_mode: html
codemirror_mode: htmlmixed codemirror_mode: htmlmixed
codemirror_mime_type: text/html codemirror_mime_type: text/html
color: "#e44b23" color: "#e34c26"
aliases: aliases:
- xhtml - xhtml
extensions: extensions:
@@ -1643,13 +1623,16 @@ HTML+Django:
tm_scope: text.html.django tm_scope: text.html.django
group: HTML group: HTML
extensions: extensions:
- ".mustache"
- ".jinja" - ".jinja"
- ".mustache"
- ".njk"
aliases: aliases:
- django - django
- html+django/jinja - html+django/jinja
- html+jinja - html+jinja
- htmldjango - htmldjango
- njk
- nunjucks
ace_mode: django ace_mode: django
codemirror_mode: django codemirror_mode: django
codemirror_mime_type: text/x-django codemirror_mime_type: text/x-django
@@ -1782,7 +1765,7 @@ Hy:
- ".hy" - ".hy"
aliases: aliases:
- hylang - hylang
tm_scope: source.hy tm_scope: none
language_id: 159 language_id: 159
HyPhy: HyPhy:
type: programming type: programming
@@ -1828,7 +1811,6 @@ INI:
language_id: 163 language_id: 163
IRC log: IRC log:
type: data type: data
search_term: irc
aliases: aliases:
- irc - irc
- irc logs - irc logs
@@ -1943,6 +1925,8 @@ JSON5:
type: data type: data
extensions: extensions:
- ".json5" - ".json5"
filenames:
- ".babelrc"
tm_scope: source.js tm_scope: source.js
ace_mode: javascript ace_mode: javascript
codemirror_mode: javascript codemirror_mode: javascript
@@ -1976,17 +1960,6 @@ JSX:
codemirror_mode: jsx codemirror_mode: jsx
codemirror_mime_type: text/jsx codemirror_mime_type: text/jsx
language_id: 178 language_id: 178
Jade:
group: HTML
type: markup
extensions:
- ".jade"
- ".pug"
tm_scope: text.jade
ace_mode: jade
codemirror_mode: pug
codemirror_mime_type: text/x-pug
language_id: 179
Jasmin: Jasmin:
type: programming type: programming
ace_mode: java ace_mode: java
@@ -2006,7 +1979,6 @@ Java:
Java Server Pages: Java Server Pages:
type: programming type: programming
group: Java group: Java
search_term: jsp
aliases: aliases:
- jsp - jsp
extensions: extensions:
@@ -2263,7 +2235,6 @@ Literate CoffeeScript:
group: CoffeeScript group: CoffeeScript
ace_mode: text ace_mode: text
wrap: true wrap: true
search_term: litcoffee
aliases: aliases:
- litcoffee - litcoffee
extensions: extensions:
@@ -2272,7 +2243,6 @@ Literate CoffeeScript:
Literate Haskell: Literate Haskell:
type: programming type: programming
group: Haskell group: Haskell
search_term: lhs
aliases: aliases:
- lhaskell - lhaskell
- lhs - lhs
@@ -2322,6 +2292,8 @@ LookML:
color: "#652B81" color: "#652B81"
extensions: extensions:
- ".lookml" - ".lookml"
- ".model.lkml"
- ".view.lkml"
tm_scope: source.yaml tm_scope: source.yaml
language_id: 211 language_id: 211
LoomScript: LoomScript:
@@ -2534,7 +2506,6 @@ Max:
aliases: aliases:
- max/msp - max/msp
- maxmsp - maxmsp
search_term: max/msp
extensions: extensions:
- ".maxpat" - ".maxpat"
- ".maxhelp" - ".maxhelp"
@@ -2586,7 +2557,6 @@ MiniD:
language_id: 231 language_id: 231
Mirah: Mirah:
type: programming type: programming
search_term: mirah
color: "#c7a938" color: "#c7a938"
extensions: extensions:
- ".druby" - ".druby"
@@ -2743,7 +2713,7 @@ Nginx:
codemirror_mime_type: text/x-nginx-conf codemirror_mime_type: text/x-nginx-conf
color: "#9469E9" color: "#9469E9"
language_id: 248 language_id: 248
Nimrod: Nim:
type: programming type: programming
color: "#37775b" color: "#37775b"
extensions: extensions:
@@ -2938,6 +2908,15 @@ OpenSCAD:
tm_scope: none tm_scope: none
ace_mode: scad ace_mode: scad
language_id: 266 language_id: 266
OpenType Feature File:
type: data
aliases:
- AFDKO
extensions:
- ".fea"
tm_scope: source.opentype
ace_mode: text
language_id: 374317347
Org: Org:
type: prose type: prose
wrap: true wrap: true
@@ -3001,6 +2980,8 @@ PHP:
- ".phps" - ".phps"
- ".phpt" - ".phpt"
filenames: filenames:
- ".php_cs"
- ".php_cs.dist"
- Phakefile - Phakefile
interpreters: interpreters:
- php - php
@@ -3155,8 +3136,8 @@ Perl6:
language_id: 283 language_id: 283
Pic: Pic:
type: markup type: markup
group: Groff group: Roff
tm_scope: "source.pic" tm_scope: source.pic
extensions: extensions:
- ".pic" - ".pic"
- ".chem" - ".chem"
@@ -3248,6 +3229,7 @@ PowerBuilder:
language_id: 292 language_id: 292
PowerShell: PowerShell:
type: programming type: programming
color: "#012456"
ace_mode: powershell ace_mode: powershell
codemirror_mode: powershell codemirror_mode: powershell
codemirror_mime_type: application/x-powershell codemirror_mime_type: application/x-powershell
@@ -3309,6 +3291,17 @@ Public Key:
codemirror_mode: asciiarmor codemirror_mode: asciiarmor
codemirror_mime_type: application/pgp codemirror_mime_type: application/pgp
language_id: 298 language_id: 298
Pug:
group: HTML
type: markup
extensions:
- ".jade"
- ".pug"
tm_scope: text.jade
ace_mode: jade
codemirror_mode: pug
codemirror_mime_type: text/x-pug
language_id: 179
Puppet: Puppet:
type: programming type: programming
color: "#302B6D" color: "#302B6D"
@@ -3360,7 +3353,9 @@ Python:
- ".cgi" - ".cgi"
- ".fcgi" - ".fcgi"
- ".gyp" - ".gyp"
- ".gypi"
- ".lmi" - ".lmi"
- ".py3"
- ".pyde" - ".pyde"
- ".pyp" - ".pyp"
- ".pyt" - ".pyt"
@@ -3371,6 +3366,7 @@ Python:
- ".wsgi" - ".wsgi"
- ".xpy" - ".xpy"
filenames: filenames:
- ".gclient"
- BUCK - BUCK
- BUILD - BUILD
- SConscript - SConscript
@@ -3384,6 +3380,15 @@ Python:
aliases: aliases:
- rusthon - rusthon
language_id: 303 language_id: 303
Python console:
type: programming
group: Python
searchable: false
aliases:
- pycon
tm_scope: text.python.console
ace_mode: text
language_id: 428
Python traceback: Python traceback:
type: data type: data
group: Python group: Python
@@ -3529,7 +3534,7 @@ Racket:
tm_scope: source.racket tm_scope: source.racket
ace_mode: lisp ace_mode: lisp
language_id: 316 language_id: 316
Ragel in Ruby Host: Ragel:
type: programming type: programming
color: "#9d5200" color: "#9d5200"
extensions: extensions:
@@ -3540,9 +3545,16 @@ Ragel in Ruby Host:
tm_scope: none tm_scope: none
ace_mode: text ace_mode: text
language_id: 317 language_id: 317
Rascal:
type: programming
color: "#fffaa0"
extensions:
- ".rsc"
tm_scope: source.rascal
ace_mode: text
language_id: 173616037
Raw token data: Raw token data:
type: data type: data
search_term: raw
aliases: aliases:
- raw - raw
extensions: extensions:
@@ -3550,6 +3562,19 @@ Raw token data:
tm_scope: none tm_scope: none
ace_mode: text ace_mode: text
language_id: 318 language_id: 318
Reason:
type: programming
group: OCaml
ace_mode: rust
codemirror_mode: rust
codemirror_mime_type: text/x-rustsrc
extensions:
- ".re"
- ".rei"
interpreters:
- ocaml
tm_scope: source.reason
language_id: 869538413
Rebol: Rebol:
type: programming type: programming
color: "#358a5b" color: "#358a5b"
@@ -3580,6 +3605,17 @@ Redcode:
tm_scope: none tm_scope: none
ace_mode: text ace_mode: text
language_id: 321 language_id: 321
Regular Expression:
type: data
extensions:
- ".regexp"
- ".regex"
aliases:
- regexp
- regex
ace_mode: text
tm_scope: source.regexp
language_id: 363378884
Ren'Py: Ren'Py:
type: programming type: programming
aliases: aliases:
@@ -3605,6 +3641,44 @@ RobotFramework:
tm_scope: text.robot tm_scope: text.robot
ace_mode: text ace_mode: text
language_id: 324 language_id: 324
Roff:
type: markup
color: "#ecdebe"
extensions:
- ".man"
- ".1"
- ".1in"
- ".1m"
- ".1x"
- ".2"
- ".3"
- ".3in"
- ".3m"
- ".3qt"
- ".3x"
- ".4"
- ".5"
- ".6"
- ".7"
- ".8"
- ".9"
- ".l"
- ".me"
- ".ms"
- ".n"
- ".rno"
- ".roff"
- ".tmac"
filenames:
- mmn
- mmt
tm_scope: text.roff
aliases:
- nroff
ace_mode: text
codemirror_mode: troff
codemirror_mime_type: text/troff
language_id: 141
Rouge: Rouge:
type: programming type: programming
ace_mode: clojure ace_mode: clojure
@@ -3660,6 +3734,7 @@ Ruby:
- Berksfile - Berksfile
- Brewfile - Brewfile
- Buildfile - Buildfile
- Dangerfile
- Deliverfile - Deliverfile
- Fastfile - Fastfile
- Gemfile - Gemfile
@@ -3753,6 +3828,7 @@ SQL:
- ".cql" - ".cql"
- ".ddl" - ".ddl"
- ".inc" - ".inc"
- ".mysql"
- ".prc" - ".prc"
- ".tab" - ".tab"
- ".udf" - ".udf"
@@ -3888,7 +3964,6 @@ Self:
language_id: 345 language_id: 345
Shell: Shell:
type: programming type: programming
search_term: bash
color: "#89e051" color: "#89e051"
aliases: aliases:
- sh - sh
@@ -4001,6 +4076,13 @@ SourcePawn:
tm_scope: source.sp tm_scope: source.sp
ace_mode: text ace_mode: text
language_id: 354 language_id: 354
Spline Font Database:
type: data
extensions:
- ".sfd"
tm_scope: text.sfd
ace_mode: yaml
language_id: 767169629
Squirrel: Squirrel:
type: programming type: programming
color: "#800000" color: "#800000"
@@ -4231,11 +4313,16 @@ Text:
- ".no" - ".no"
filenames: filenames:
- COPYING - COPYING
- COPYRIGHT.regex
- FONTLOG
- INSTALL - INSTALL
- INSTALL.mysql
- LICENSE - LICENSE
- LICENSE.mysql
- NEWS - NEWS
- README.1ST - README.1ST
- README.me - README.me
- README.mysql
- click.me - click.me
- delete.me - delete.me
- keep.me - keep.me
@@ -4326,6 +4413,15 @@ Unity3D Asset:
- ".unity" - ".unity"
tm_scope: source.yaml tm_scope: source.yaml
language_id: 380 language_id: 380
Unix Assembly:
type: programming
group: Assembly
extensions:
- ".s"
- ".ms"
tm_scope: source.assembly
ace_mode: assembly_x86
language_id: 120
Uno: Uno:
type: programming type: programming
extensions: extensions:
@@ -4398,13 +4494,13 @@ Verilog:
codemirror_mode: verilog codemirror_mode: verilog
codemirror_mime_type: text/x-verilog codemirror_mime_type: text/x-verilog
language_id: 387 language_id: 387
VimL: Vim script:
type: programming type: programming
color: "#199f4b" color: "#199f4b"
search_term: vim
tm_scope: source.viml tm_scope: source.viml
aliases: aliases:
- vim - vim
- viml
- nvim - nvim
extensions: extensions:
- ".vim" - ".vim"
@@ -4513,6 +4609,15 @@ XC:
codemirror_mode: clike codemirror_mode: clike
codemirror_mime_type: text/x-csrc codemirror_mime_type: text/x-csrc
language_id: 398 language_id: 398
XCompose:
type: data
filenames:
- ".XCompose"
- XCompose
- xcompose
tm_scope: config.xcompose
ace_mode: text
language_id: 225167241
XML: XML:
type: data type: data
ace_mode: xml ace_mode: xml
@@ -4706,6 +4811,7 @@ YAML:
- ".syntax" - ".syntax"
- ".yaml" - ".yaml"
- ".yaml-tmlanguage" - ".yaml-tmlanguage"
- ".yml.mysql"
filenames: filenames:
- ".clang-format" - ".clang-format"
ace_mode: yaml ace_mode: yaml
@@ -4757,7 +4863,6 @@ desktop:
eC: eC:
type: programming type: programming
color: "#913960" color: "#913960"
search_term: ec
extensions: extensions:
- ".ec" - ".ec"
- ".eh" - ".eh"
@@ -4807,7 +4912,6 @@ ooc:
reStructuredText: reStructuredText:
type: prose type: prose
wrap: true wrap: true
search_term: rst
aliases: aliases:
- rst - rst
extensions: extensions:

View File

@@ -26,4 +26,4 @@
- Shell - Shell
- Swift - Swift
- TeX - TeX
- VimL - Vim script

View File

@@ -0,0 +1,10 @@
module Linguist
module Strategy
# Detects language based on extension
class Extension
def self.call(blob, _)
Language.find_by_extension(blob.name.to_s)
end
end
end
end

View File

@@ -1,9 +1,10 @@
module Linguist module Linguist
module Strategy module Strategy
# Detects language based on filename and/or extension # Detects language based on filename
class Filename class Filename
def self.call(blob, _) def self.call(blob, _)
Language.find_by_filename(blob.name.to_s) name = blob.name.to_s
Language.find_by_filename(name)
end end
end end
end end

View File

@@ -50,6 +50,9 @@
# Go dependencies # Go dependencies
- Godeps/_workspace/ - Godeps/_workspace/
# GNU indent profiles
- .indent.pro
# Minified JavaScript and CSS # Minified JavaScript and CSS
- (\.|-)min\.(js|css)$ - (\.|-)min\.(js|css)$
@@ -235,6 +238,12 @@
# BuddyBuild # BuddyBuild
- BuddyBuildSDK.framework/ - BuddyBuildSDK.framework/
# Realm
- Realm.framework
# RealmSwift
- RealmSwift.framework
# git config files # git config files
- gitattributes$ - gitattributes$
- gitignore$ - gitignore$

View File

@@ -1,3 +1,3 @@
module Linguist module Linguist
VERSION = "4.8.16" VERSION = "5.0.5"
end end

190
samples/ABNF/toml.abnf Normal file
View File

@@ -0,0 +1,190 @@
; Source: https://github.com/toml-lang/toml
; License: MIT
;; This is an attempt to define TOML in ABNF according to the grammar defined
;; in RFC 4234 (http://www.ietf.org/rfc/rfc4234.txt).
;; TOML
toml = expression *( newline expression )
expression = (
ws /
ws comment /
ws keyval ws [ comment ] /
ws table ws [ comment ]
)
;; Newline
newline = (
%x0A / ; LF
%x0D.0A ; CRLF
)
newlines = 1*newline
;; Whitespace
ws = *(
%x20 / ; Space
%x09 ; Horizontal tab
)
;; Comment
comment-start-symbol = %x23 ; #
non-eol = %x09 / %x20-10FFFF
comment = comment-start-symbol *non-eol
;; Key-Value pairs
keyval-sep = ws %x3D ws ; =
keyval = key keyval-sep val
key = unquoted-key / quoted-key
unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _
quoted-key = quotation-mark 1*basic-char quotation-mark ; See Basic Strings
val = integer / float / string / boolean / date-time / array / inline-table
;; Table
table = std-table / array-table
;; Standard Table
std-table-open = %x5B ws ; [ Left square bracket
std-table-close = ws %x5D ; ] Right square bracket
table-key-sep = ws %x2E ws ; . Period
std-table = std-table-open key *( table-key-sep key) std-table-close
;; Array Table
array-table-open = %x5B.5B ws ; [[ Double left square bracket
array-table-close = ws %x5D.5D ; ]] Double right square bracket
array-table = array-table-open key *( table-key-sep key) array-table-close
;; Integer
integer = [ minus / plus ] int
minus = %x2D ; -
plus = %x2B ; +
digit1-9 = %x31-39 ; 1-9
underscore = %x5F ; _
int = DIGIT / digit1-9 1*( DIGIT / underscore DIGIT )
;; Float
float = integer ( frac / frac exp / exp )
zero-prefixable-int = DIGIT *( DIGIT / underscore DIGIT )
frac = decimal-point zero-prefixable-int
decimal-point = %x2E ; .
exp = e integer
e = %x65 / %x45 ; e E
;; String
string = basic-string / ml-basic-string / literal-string / ml-literal-string
;; Basic String
basic-string = quotation-mark *basic-char quotation-mark
quotation-mark = %x22 ; "
basic-char = basic-unescaped / escaped
escaped = escape ( %x22 / ; " quotation mark U+0022
%x5C / ; \ reverse solidus U+005C
%x2F / ; / solidus U+002F
%x62 / ; b backspace U+0008
%x66 / ; f form feed U+000C
%x6E / ; n line feed U+000A
%x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG / ; uXXXX U+XXXX
%x55 8HEXDIG ) ; UXXXXXXXX U+XXXXXXXX
basic-unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
escape = %x5C ; \
;; Multiline Basic String
ml-basic-string-delim = quotation-mark quotation-mark quotation-mark
ml-basic-string = ml-basic-string-delim ml-basic-body ml-basic-string-delim
ml-basic-body = *( ml-basic-char / newline / ( escape newline ))
ml-basic-char = ml-basic-unescaped / escaped
ml-basic-unescaped = %x20-5B / %x5D-10FFFF
;; Literal String
literal-string = apostraphe *literal-char apostraphe
apostraphe = %x27 ; ' Apostrophe
literal-char = %x09 / %x20-26 / %x28-10FFFF
;; Multiline Literal String
ml-literal-string-delim = apostraphe apostraphe apostraphe
ml-literal-string = ml-literal-string-delim ml-literal-body ml-literal-string-delim
ml-literal-body = *( ml-literal-char / newline )
ml-literal-char = %x09 / %x20-10FFFF
;; Boolean
boolean = true / false
true = %x74.72.75.65 ; true
false = %x66.61.6C.73.65 ; false
;; Datetime (as defined in RFC 3339)
date-fullyear = 4DIGIT
date-month = 2DIGIT ; 01-12
date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year
time-hour = 2DIGIT ; 00-23
time-minute = 2DIGIT ; 00-59
time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second rules
time-secfrac = "." 1*DIGIT
time-numoffset = ( "+" / "-" ) time-hour ":" time-minute
time-offset = "Z" / time-numoffset
partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
full-date = date-fullyear "-" date-month "-" date-mday
full-time = partial-time time-offset
date-time = full-date "T" full-time
;; Array
array-open = %x5B ws ; [
array-close = ws %x5D ; ]
array = array-open array-values array-close
array-values = [ val [ array-sep ] [ ( comment newlines) / newlines ] /
val array-sep [ ( comment newlines) / newlines ] array-values ]
array-sep = ws %x2C ws ; , Comma
;; Inline Table
inline-table-open = %x7B ws ; {
inline-table-close = ws %x7D ; }
inline-table-sep = ws %x2C ws ; , Comma
inline-table = inline-table-open inline-table-keyvals inline-table-close
inline-table-keyvals = [ inline-table-keyvals-non-empty ]
inline-table-keyvals-non-empty = key keyval-sep val /
key keyval-sep val inline-table-sep inline-table-keyvals-non-empty
;; Built-in ABNF terms, reproduced here for clarity
; ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
; DIGIT = %x30-39 ; 0-9
; HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"

View File

@@ -0,0 +1,46 @@
#include <iostream>
#define YYCTYPE unsigned char
#define YYCURSOR cursor
#define YYLIMIT cursor
#define YYMARKER marker
#define YYFILL(n)
bool scan(const char *text)
{
YYCTYPE *start = (YYCTYPE *)text;
YYCTYPE *cursor = (YYCTYPE *)text;
YYCTYPE *marker = (YYCTYPE *)text;
next:
YYCTYPE *token = cursor;
/*!re2c
'(This file must be converted with BinHex 4.0)'
{
if (token == start || *(token - 1) == '\n')
return true; else goto next;
}
[\001-\377]
{ goto next; }
[\000]
{ return false; }
*/
return false;
}
#define do_scan(str, expect) \
res = scan(str) == expect ? 0 : 1; \
std::cerr << str << "\t-\t" << (res ? "fail" : "ok") << std::endl; \
result += res
/*!max:re2c */
int main(int,void**)
{
int res, result = 0;
do_scan("(This file must be converted with BinHex 4.0)", 1);
do_scan("x(This file must be converted with BinHex 4.0)", 0);
do_scan("(This file must be converted with BinHex 4.0)x", 1);
do_scan("x(This file must be converted with BinHex 4.0)x", 0);
return result;
}

239
samples/C++/cnokw.re Normal file
View File

@@ -0,0 +1,239 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ADDEQ 257
#define ANDAND 258
#define ANDEQ 259
#define ARRAY 260
#define ASM 261
#define AUTO 262
#define BREAK 263
#define CASE 264
#define CHAR 265
#define CONST 266
#define CONTINUE 267
#define DECR 268
#define DEFAULT 269
#define DEREF 270
#define DIVEQ 271
#define DO 272
#define DOUBLE 273
#define ELLIPSIS 274
#define ELSE 275
#define ENUM 276
#define EQL 277
#define EXTERN 278
#define FCON 279
#define FLOAT 280
#define FOR 281
#define FUNCTION 282
#define GEQ 283
#define GOTO 284
#define ICON 285
#define ID 286
#define IF 287
#define INCR 288
#define INT 289
#define LEQ 290
#define LONG 291
#define LSHIFT 292
#define LSHIFTEQ 293
#define MODEQ 294
#define MULEQ 295
#define NEQ 296
#define OREQ 297
#define OROR 298
#define POINTER 299
#define REGISTER 300
#define RETURN 301
#define RSHIFT 302
#define RSHIFTEQ 303
#define SCON 304
#define SHORT 305
#define SIGNED 306
#define SIZEOF 307
#define STATIC 308
#define STRUCT 309
#define SUBEQ 310
#define SWITCH 311
#define TYPEDEF 312
#define UNION 313
#define UNSIGNED 314
#define VOID 315
#define VOLATILE 316
#define WHILE 317
#define XOREQ 318
#define EOI 319
typedef unsigned int uint;
typedef unsigned char uchar;
#define BSIZE 8192
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n) {cursor = fill(s, cursor);}
#define RET(i) {s->cur = cursor; return i;}
typedef struct Scanner {
int fd;
uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
uint line;
} Scanner;
uchar *fill(Scanner *s, uchar *cursor){
if(!s->eof){
uint cnt = s->tok - s->bot;
if(cnt){
memcpy(s->bot, s->tok, s->lim - s->tok);
s->tok = s->bot;
s->ptr -= cnt;
cursor -= cnt;
s->pos -= cnt;
s->lim -= cnt;
}
if((s->top - s->lim) < BSIZE){
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
memcpy(buf, s->tok, s->lim - s->tok);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
cursor = &buf[cursor - s->bot];
s->pos = &buf[s->pos - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[BSIZE];
free(s->bot);
s->bot = buf;
}
if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
}
s->lim += cnt;
}
return cursor;
}
int scan(Scanner *s){
uchar *cursor = s->cur;
std:
s->tok = cursor;
/*!re2c
any = [\000-\377];
O = [0-7];
D = [0-9];
L = [a-zA-Z_];
H = [a-fA-F0-9];
E = [Ee] [+-]? D+;
FS = [fFlL];
IS = [uUlL]*;
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
*/
/*!re2c
"/*" { goto comment; }
L (L|D)* { RET(ID); }
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
(['] (ESC|any\[\n\\'])* ['])
{ RET(ICON); }
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
{ RET(FCON); }
(["] (ESC|any\[\n\\"])* ["])
{ RET(SCON); }
"..." { RET(ELLIPSIS); }
">>=" { RET(RSHIFTEQ); }
"<<=" { RET(LSHIFTEQ); }
"+=" { RET(ADDEQ); }
"-=" { RET(SUBEQ); }
"*=" { RET(MULEQ); }
"/=" { RET(DIVEQ); }
"%=" { RET(MODEQ); }
"&=" { RET(ANDEQ); }
"^=" { RET(XOREQ); }
"|=" { RET(OREQ); }
">>" { RET(RSHIFT); }
"<<" { RET(LSHIFT); }
"++" { RET(INCR); }
"--" { RET(DECR); }
"->" { RET(DEREF); }
"&&" { RET(ANDAND); }
"||" { RET(OROR); }
"<=" { RET(LEQ); }
">=" { RET(GEQ); }
"==" { RET(EQL); }
"!=" { RET(NEQ); }
";" { RET(';'); }
"{" { RET('{'); }
"}" { RET('}'); }
"," { RET(','); }
":" { RET(':'); }
"=" { RET('='); }
"(" { RET('('); }
")" { RET(')'); }
"[" { RET('['); }
"]" { RET(']'); }
"." { RET('.'); }
"&" { RET('&'); }
"!" { RET('!'); }
"~" { RET('~'); }
"-" { RET('-'); }
"+" { RET('+'); }
"*" { RET('*'); }
"/" { RET('/'); }
"%" { RET('%'); }
"<" { RET('<'); }
">" { RET('>'); }
"^" { RET('^'); }
"|" { RET('|'); }
"?" { RET('?'); }
[ \t\v\f]+ { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->pos = cursor; s->line++;
goto std;
}
any
{
printf("unexpected character: %c\n", *s->tok);
goto std;
}
*/
comment:
/*!re2c
"*/" { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->tok = s->pos = cursor; s->line++;
goto comment;
}
any { goto comment; }
*/
}
main(){
Scanner in;
int t;
memset((char*) &in, 0, sizeof(in));
in.fd = 0;
while((t = scan(&in)) != EOI){
/*
printf("%d\t%.*s\n", t, in.cur - in.tok, in.tok);
printf("%d\n", t);
*/
}
close(in.fd);
}

63
samples/C++/cvsignore.re Normal file
View File

@@ -0,0 +1,63 @@
#define YYFILL(n) if (cursor >= limit) break;
#define YYCTYPE char
#define YYCURSOR cursor
#define YYLIMIT limit
#define YYMARKER marker
/*!re2c
any = (.|"\n");
value = (":" (.\"$")+)?;
cvsdat = "Date";
cvsid = "Id";
cvslog = "Log";
cvsrev = "Revision";
cvssrc = "Source";
*/
#define APPEND(text) \
append(output, outsize, text, sizeof(text) - sizeof(YYCTYPE))
inline void append(YYCTYPE *output, size_t & outsize, const YYCTYPE * text, size_t len)
{
memcpy(output + outsize, text, len);
outsize += (len / sizeof(YYCTYPE));
}
void scan(YYCTYPE *pText, size_t *pSize, int *pbChanged)
{
// rule
// scan lines
// find $ in lines
// compact $<keyword>: .. $ to $<keyword>$
YYCTYPE *output;
const YYCTYPE *cursor, *limit, *marker;
cursor = marker = output = *pText;
size_t insize = *pSize;
size_t outsize = 0;
limit = cursor + insize;
while(1) {
loop:
/*!re2c
"$" cvsdat value "$" { APPEND(L"$" L"Date$"); goto loop; }
"$" cvsid value "$" { APPEND(L"$" L"Id$"); goto loop; }
"$" cvslog value "$" { APPEND(L"$" L"Log$"); goto loop; }
"$" cvsrev value "$" { APPEND(L"$" L"Revision$"); goto loop; }
"$" cvssrc value "$" { APPEND(L"$" L"Source$"); goto loop; }
any { output[outsize++] = cursor[-1]; if (cursor >= limit) break; goto loop; }
*/
}
output[outsize] = '\0';
// set the new size
*pSize = outsize;
*pbChanged = (insize == outsize) ? 0 : 1;
}

13
samples/C++/simple.re Normal file
View File

@@ -0,0 +1,13 @@
#define NULL ((char*) 0)
char *scan(char *p){
char *q;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT p
#define YYMARKER q
#define YYFILL(n)
/*!re2c
[0-9]+ {return YYCURSOR;}
[\000-\377] {return NULL;}
*/
}

View File

@@ -1,707 +0,0 @@
Inductive day : Type :=
| monday : day
| tuesday : day
| wednesday : day
| thursday : day
| friday : day
| saturday : day
| sunday : day.
Definition next_weekday (d:day) : day :=
match d with
| monday => tuesday
| tuesday => wednesday
| wednesday => thursday
| thursday => friday
| friday => monday
| saturday => monday
| sunday => monday
end.
Example test_next_weekday:
(next_weekday (next_weekday saturday)) = tuesday.
Proof. simpl. reflexivity. Qed.
Inductive bool : Type :=
| true : bool
| false : bool.
Definition negb (b:bool) : bool :=
match b with
| true => false
| false => true
end.
Definition andb (b1:bool) (b2:bool) : bool :=
match b1 with
| true => b2
| false => false
end.
Definition orb (b1:bool) (b2:bool) : bool :=
match b1 with
| true => true
| false => b2
end.
Example test_orb1: (orb true false) = true.
Proof. simpl. reflexivity. Qed.
Example test_orb2: (orb false false) = false.
Proof. simpl. reflexivity. Qed.
Example test_orb3: (orb false true) = true.
Proof. simpl. reflexivity. Qed.
Example test_orb4: (orb true true) = true.
Proof. simpl. reflexivity. Qed.
Definition nandb (b1: bool) (b2:bool) : bool :=
match b1 with
| true => match b2 with
| false => true
| true => false
end
| false => true
end.
Example test_nandb1: (nandb true false) = true.
Proof. simpl. reflexivity. Qed.
Example test_nandb2: (nandb false false) = true.
Proof. simpl. reflexivity. Qed.
Example test_nandb3: (nandb false true) = true.
Proof. simpl. reflexivity. Qed.
Example test_nandb4: (nandb true true) = false.
Proof. simpl. reflexivity. Qed.
Definition andb3 (b1: bool) (b2:bool) (b3:bool) : bool :=
match b1 with
| false => false
| true => match b2 with
| false => false
| true => b3
end
end.
Example test_andb31: (andb3 true true true) = true.
Proof. simpl. reflexivity. Qed.
Example test_andb32: (andb3 false true true) = false.
Proof. simpl. reflexivity. Qed.
Example test_andb33: (andb3 true false true) = false.
Proof. simpl. reflexivity. Qed.
Example test_andb34: (andb3 true true false) = false.
Proof. simpl. reflexivity. Qed.
Module Playground1.
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
Definition pred (n : nat) : nat :=
match n with
| O => O
| S n' => n'
end.
Definition minustwo (n : nat) : nat :=
match n with
| O => O
| S O => O
| S (S n') => n'
end.
Fixpoint evenb (n : nat) : bool :=
match n with
| O => true
| S O => false
| S (S n') => evenb n'
end.
Definition oddb (n : nat) : bool := negb (evenb n).
Example test_oddb1: (oddb (S O)) = true.
Proof. reflexivity. Qed.
Example test_oddb2: (oddb (S (S (S (S O))))) = false.
Proof. reflexivity. Qed.
Fixpoint plus (n : nat) (m : nat) : nat :=
match n with
| O => m
| S n' => S (plus n' m)
end.
Fixpoint mult (n m : nat) : nat :=
match n with
| O => O
| S n' => plus m (mult n' m)
end.
Fixpoint minus (n m : nat) : nat :=
match n, m with
| O, _ => n
| S n', O => S n'
| S n', S m' => minus n' m'
end.
Fixpoint exp (base power : nat) : nat :=
match power with
| O => S O
| S p => mult base (exp base p)
end.
Fixpoint factorial (n : nat) : nat :=
match n with
| O => S O
| S n' => mult n (factorial n')
end.
Example test_factorial1: (factorial (S (S (S O)))) = (S (S (S (S (S (S O)))))).
Proof. simpl. reflexivity. Qed.
Notation "x + y" := (plus x y) (at level 50, left associativity) : nat_scope.
Notation "x - y" := (minus x y) (at level 50, left associativity) : nat_scope.
Notation "x * y" := (mult x y) (at level 40, left associativity) : nat_scope.
Fixpoint beq_nat (n m : nat) : bool :=
match n with
| O => match m with
| O => true
| S m' => false
end
| S n' => match m with
| O => false
| S m' => beq_nat n' m'
end
end.
Fixpoint ble_nat (n m : nat) : bool :=
match n with
| O => true
| S n' =>
match m with
| O => false
| S m' => ble_nat n' m'
end
end.
Example test_ble_nat1: (ble_nat (S (S O)) (S (S O))) = true.
Proof. simpl. reflexivity. Qed.
Example test_ble_nat2: (ble_nat (S (S O)) (S (S (S (S O))))) = true.
Proof. simpl. reflexivity. Qed.
Example test_ble_nat3: (ble_nat (S (S (S (S O)))) (S (S O))) = false.
Proof. simpl. reflexivity. Qed.
Definition blt_nat (n m : nat) : bool :=
(andb (negb (beq_nat n m)) (ble_nat n m)).
Example test_blt_nat1: (blt_nat (S (S O)) (S (S O))) = false.
Proof. simpl. reflexivity. Qed.
Example test_blt_nat3: (blt_nat (S (S (S (S O)))) (S (S O))) = false.
Proof. simpl. reflexivity. Qed.
Example test_blt_nat2 : (blt_nat (S (S O)) (S (S (S (S O))))) = true.
Proof. simpl. reflexivity. Qed.
Theorem plus_O_n : forall n : nat, O + n = n.
Proof.
simpl. reflexivity. Qed.
Theorem plus_O_n' : forall n : nat, O + n = n.
Proof.
reflexivity. Qed.
Theorem plus_O_n'' : forall n : nat, O + n = n.
Proof.
intros n. reflexivity. Qed.
Theorem plus_1_1 : forall n : nat, (S O) + n = S n.
Proof.
intros n. reflexivity. Qed.
Theorem mult_0_1: forall n : nat, O * n = O.
Proof.
intros n. reflexivity. Qed.
Theorem plus_id_example : forall n m:nat,
n = m -> n + n = m + m.
Proof.
intros n m.
intros H.
rewrite -> H.
reflexivity. Qed.
Theorem plus_id_exercise : forall n m o: nat,
n = m -> m = o -> n + m = m + o.
Proof.
intros n m o.
intros H.
intros H'.
rewrite -> H.
rewrite <- H'.
reflexivity.
Qed.
Theorem mult_0_plus : forall n m : nat,
(O + n) * m = n * m.
Proof.
intros n m.
rewrite -> plus_O_n.
reflexivity. Qed.
Theorem mult_1_plus : forall n m: nat,
((S O) + n) * m = m + (n * m).
Proof.
intros n m.
rewrite -> plus_1_1.
reflexivity.
Qed.
Theorem mult_1 : forall n : nat,
n * (S O) = n.
Proof.
intros n.
induction n as [| n'].
reflexivity.
simpl.
rewrite -> IHn'.
reflexivity.
Qed.
Theorem plus_1_neq_0 : forall n : nat,
beq_nat (n + (S O)) O = false.
Proof.
intros n.
destruct n as [| n'].
reflexivity.
reflexivity.
Qed.
Theorem zero_nbeq_plus_1 : forall n : nat,
beq_nat O (n + (S O)) = false.
Proof.
intros n.
destruct n.
reflexivity.
reflexivity.
Qed.
Require String. Open Scope string_scope.
Ltac move_to_top x :=
match reverse goal with
| H : _ |- _ => try move x after H
end.
Tactic Notation "assert_eq" ident(x) constr(v) :=
let H := fresh in
assert (x = v) as H by reflexivity;
clear H.
Tactic Notation "Case_aux" ident(x) constr(name) :=
first [
set (x := name); move_to_top x
| assert_eq x name; move_to_top x
| fail 1 "because we are working on a different case" ].
Ltac Case name := Case_aux Case name.
Ltac SCase name := Case_aux SCase name.
Ltac SSCase name := Case_aux SSCase name.
Ltac SSSCase name := Case_aux SSSCase name.
Ltac SSSSCase name := Case_aux SSSSCase name.
Ltac SSSSSCase name := Case_aux SSSSSCase name.
Ltac SSSSSSCase name := Case_aux SSSSSSCase name.
Ltac SSSSSSSCase name := Case_aux SSSSSSSCase name.
Theorem andb_true_elim1 : forall b c : bool,
andb b c = true -> b = true.
Proof.
intros b c H.
destruct b.
Case "b = true".
reflexivity.
Case "b = false".
rewrite <- H. reflexivity. Qed.
Theorem plus_0_r : forall n : nat, n + O = n.
Proof.
intros n. induction n as [| n'].
Case "n = 0". reflexivity.
Case "n = S n'". simpl. rewrite -> IHn'. reflexivity. Qed.
Theorem minus_diag : forall n,
minus n n = O.
Proof.
intros n. induction n as [| n'].
Case "n = 0".
simpl. reflexivity.
Case "n = S n'".
simpl. rewrite -> IHn'. reflexivity. Qed.
Theorem mult_0_r : forall n:nat,
n * O = O.
Proof.
intros n. induction n as [| n'].
Case "n = 0".
reflexivity.
Case "n = S n'".
simpl. rewrite -> IHn'. reflexivity. Qed.
Theorem plus_n_Sm : forall n m : nat,
S (n + m) = n + (S m).
Proof.
intros n m. induction n as [| n'].
Case "n = 0".
reflexivity.
Case "n = S n'".
simpl. rewrite -> IHn'. reflexivity. Qed.
Theorem plus_assoc : forall n m p : nat,
n + (m + p) = (n + m) + p.
Proof.
intros n m p.
induction n as [| n'].
reflexivity.
simpl.
rewrite -> IHn'.
reflexivity. Qed.
Theorem plus_distr : forall n m: nat, S (n + m) = n + (S m).
Proof.
intros n m. induction n as [| n'].
Case "n = 0".
reflexivity.
Case "n = S n'".
simpl. rewrite -> IHn'. reflexivity. Qed.
Theorem mult_distr : forall n m: nat, n * ((S O) + m) = n * (S m).
Proof.
intros n m.
induction n as [| n'].
reflexivity.
reflexivity.
Qed.
Theorem plus_comm : forall n m : nat,
n + m = m + n.
Proof.
intros n m.
induction n as [| n'].
Case "n = 0".
simpl.
rewrite -> plus_0_r.
reflexivity.
Case "n = S n'".
simpl.
rewrite -> IHn'.
rewrite -> plus_distr.
reflexivity. Qed.
Fixpoint double (n:nat) :=
match n with
| O => O
| S n' => S (S (double n'))
end.
Lemma double_plus : forall n, double n = n + n.
Proof.
intros n. induction n as [| n'].
Case "n = 0".
reflexivity.
Case "n = S n'".
simpl. rewrite -> IHn'.
rewrite -> plus_distr. reflexivity.
Qed.
Theorem beq_nat_refl : forall n : nat,
true = beq_nat n n.
Proof.
intros n. induction n as [| n'].
Case "n = 0".
reflexivity.
Case "n = S n".
simpl. rewrite <- IHn'.
reflexivity. Qed.
Theorem plus_rearrange: forall n m p q : nat,
(n + m) + (p + q) = (m + n) + (p + q).
Proof.
intros n m p q.
assert(H: n + m = m + n).
Case "Proof by assertion".
rewrite -> plus_comm. reflexivity.
rewrite -> H. reflexivity. Qed.
Theorem plus_swap : forall n m p: nat,
n + (m + p) = m + (n + p).
Proof.
intros n m p.
rewrite -> plus_assoc.
assert(H: m + (n + p) = (m + n) + p).
rewrite -> plus_assoc.
reflexivity.
rewrite -> H.
assert(H2: m + n = n + m).
rewrite -> plus_comm.
reflexivity.
rewrite -> H2.
reflexivity.
Qed.
Theorem plus_swap' : forall n m p: nat,
n + (m + p) = m + (n + p).
Proof.
intros n m p.
rewrite -> plus_assoc.
assert(H: m + (n + p) = (m + n) + p).
rewrite -> plus_assoc.
reflexivity.
rewrite -> H.
replace (m + n) with (n + m).
rewrite -> plus_comm.
reflexivity.
rewrite -> plus_comm.
reflexivity.
Qed.
Theorem mult_1_distr: forall m n: nat,
n * ((S O) + m) = n * (S O) + n * m.
Proof.
intros n m.
rewrite -> mult_1.
rewrite -> plus_1_1.
simpl.
induction m as [|m'].
simpl.
reflexivity.
simpl.
rewrite -> plus_swap.
rewrite <- IHm'.
reflexivity.
Qed.
Theorem mult_comm: forall m n : nat,
m * n = n * m.
Proof.
intros m n.
induction n as [| n'].
Case "n = 0".
simpl.
rewrite -> mult_0_r.
reflexivity.
Case "n = S n'".
simpl.
rewrite <- mult_distr.
rewrite -> mult_1_distr.
rewrite -> mult_1.
rewrite -> IHn'.
reflexivity.
Qed.
Theorem evenb_next : forall n : nat,
evenb n = evenb (S (S n)).
Proof.
intros n.
Admitted.
Theorem negb_negb : forall n : bool,
n = negb (negb n).
Proof.
intros n.
destruct n.
reflexivity.
reflexivity.
Qed.
Theorem evenb_n_oddb_Sn : forall n : nat,
evenb n = negb (evenb (S n)).
Proof.
intros n.
induction n as [|n'].
reflexivity.
assert(H: evenb n' = evenb (S (S n'))).
reflexivity.
rewrite <- H.
rewrite -> IHn'.
rewrite <- negb_negb.
reflexivity.
Qed.
(*Fixpoint bad (n : nat) : bool :=
match n with
| O => true
| S O => bad (S n)
| S (S n') => bad n'
end.*)
Theorem ble_nat_refl : forall n:nat,
true = ble_nat n n.
Proof.
intros n.
induction n as [|n'].
Case "n = 0".
reflexivity.
Case "n = S n".
simpl.
rewrite <- IHn'.
reflexivity.
Qed.
Theorem zero_nbeq_S : forall n: nat,
beq_nat O (S n) = false.
Proof.
intros n.
reflexivity.
Qed.
Theorem andb_false_r : forall b : bool,
andb b false = false.
Proof.
intros b.
destruct b.
reflexivity.
reflexivity.
Qed.
Theorem plus_ble_compat_1 : forall n m p : nat,
ble_nat n m = true -> ble_nat (p + n) (p + m) = true.
Proof.
intros n m p.
intros H.
induction p.
Case "p = 0".
simpl.
rewrite -> H.
reflexivity.
Case "p = S p'".
simpl.
rewrite -> IHp.
reflexivity.
Qed.
Theorem S_nbeq_0 : forall n:nat,
beq_nat (S n) O = false.
Proof.
intros n.
reflexivity.
Qed.
Theorem mult_1_1 : forall n:nat, (S O) * n = n.
Proof.
intros n.
simpl.
rewrite -> plus_0_r.
reflexivity. Qed.
Theorem all3_spec : forall b c : bool,
orb (andb b c)
(orb (negb b)
(negb c))
= true.
Proof.
intros b c.
destruct b.
destruct c.
reflexivity.
reflexivity.
reflexivity.
Qed.
Lemma mult_plus_1 : forall n m : nat,
S(m + n) = m + (S n).
Proof.
intros n m.
induction m.
reflexivity.
simpl.
rewrite -> IHm.
reflexivity.
Qed.
Theorem mult_mult : forall n m : nat,
n * (S m) = n * m + n.
Proof.
intros n m.
induction n.
reflexivity.
simpl.
rewrite -> IHn.
rewrite -> plus_assoc.
rewrite -> mult_plus_1.
reflexivity.
Qed.
Theorem mult_plus_distr_r : forall n m p:nat,
(n + m) * p = (n * p) + (m * p).
Proof.
intros n m p.
induction p.
rewrite -> mult_0_r.
rewrite -> mult_0_r.
rewrite -> mult_0_r.
reflexivity.
rewrite -> mult_mult.
rewrite -> mult_mult.
rewrite -> mult_mult.
rewrite -> IHp.
assert(H1: ((n * p) + n) + (m * p + m) = (n * p) + (n + (m * p + m))).
rewrite <- plus_assoc.
reflexivity.
rewrite -> H1.
assert(H2: (n + (m * p + m)) = (m * p + (n + m))).
rewrite -> plus_swap.
reflexivity.
rewrite -> H2.
assert(H3: (n * p) + (m * p + (n + m)) = ((n * p ) + (m * p)) + (n + m)).
rewrite -> plus_assoc.
reflexivity.
rewrite -> H3.
reflexivity.
Qed.
Theorem mult_assoc : forall n m p : nat,
n * (m * p) = (n * m) * p.
Proof.
intros n m p.
induction n.
simpl.
reflexivity.
simpl.
rewrite -> mult_plus_distr_r.
rewrite -> IHn.
reflexivity.
Qed.
Inductive bin : Type :=
| BO : bin
| D : bin -> bin
| M : bin -> bin.
Fixpoint incbin (n : bin) : bin :=
match n with
| BO => M (BO)
| D n' => M n'
| M n' => D (incbin n')
end.
Fixpoint bin2un (n : bin) : nat :=
match n with
| BO => O
| D n' => double (bin2un n')
| M n' => S (double (bin2un n'))
end.
Theorem bin_comm : forall n : bin,
bin2un(incbin n) = S (bin2un n).
Proof.
intros n.
induction n.
reflexivity.
reflexivity.
simpl.
rewrite -> IHn.
reflexivity.
Qed.
End Playground1.

85
samples/Coq/Computation.v Normal file
View File

@@ -0,0 +1,85 @@
(** The definition of computations, used to represent interactive programs. *)
Require Import Coq.NArith.NArith.
Require Import ListString.All.
Local Open Scope type.
(** System calls. *)
Module Command.
Inductive t :=
| AskCard
| AskPIN
| CheckPIN (pin : N)
| AskAmount
| CheckAmount (amount : N)
| GiveCard
| GiveAmount (amount : N)
| ShowError (message : LString.t).
(** The type of an answer for a command depends on the value of the command. *)
Definition answer (command : t) : Type :=
match command with
| AskCard => bool (* If the given card seems valid. *)
| AskPIN => option N (* A number or cancellation. *)
| CheckPIN _ => bool (* If the PIN number is valid. *)
| AskAmount => option N (* A number or cancellation. *)
| CheckAmount _ => bool (* If the amount can be withdrawn. *)
| GiveCard => bool (* If the card was given. *)
| GiveAmount _ => bool (* If the money was given. *)
| ShowError _ => unit (* Show an error message. *)
end.
End Command.
(** Computations with I/Os. *)
Module C.
(** A computation can either does nothing, or do a system call and wait
for the answer to run another computation. *)
Inductive t : Type :=
| Ret : t
| Call : forall (command : Command.t), (Command.answer command -> t) -> t.
Arguments Ret.
Arguments Call _ _.
(** Some optional notations. *)
Module Notations.
(** A nicer notation for `Ret`. *)
Definition ret : t :=
Ret.
(** We define an explicit apply function so that Coq does not try to expand
the notations everywhere. *)
Definition apply {A B} (f : A -> B) (x : A) := f x.
(** System call. *)
Notation "'call!' answer ':=' command 'in' X" :=
(Call command (fun answer => X))
(at level 200, answer ident, command at level 100, X at level 200).
(** System call with typed answer. *)
Notation "'call!' answer : A ':=' command 'in' X" :=
(Call command (fun (answer : A) => X))
(at level 200, answer ident, command at level 100, A at level 200, X at level 200).
(** System call ignoring the answer. *)
Notation "'do_call!' command 'in' X" :=
(Call command (fun _ => X))
(at level 200, command at level 100, X at level 200).
(** This notation is useful to compose computations which wait for a
continuation. We do not have an explicit bind operator to simplify the
language and the proofs. *)
Notation "'let!' x ':=' X 'in' Y" :=
(apply X (fun x => Y))
(at level 200, x ident, X at level 100, Y at level 200).
(** Let with a typed answer. *)
Notation "'let!' x : A ':=' X 'in' Y" :=
(apply X (fun (x : A) => Y))
(at level 200, x ident, X at level 100, A at level 200, Y at level 200).
(** Let ignoring the answer. *)
Notation "'do!' X 'in' Y" :=
(apply X (fun _ => Y))
(at level 200, X at level 100, Y at level 200).
End Notations.
End C.

View File

@@ -1,290 +0,0 @@
(** A development of Treesort on Heap trees. It has an average
complexity of O(n.log n) but of O() in the worst case (e.g. if
the list is already sorted) *)
(* G. Huet 1-9-95 uses Multiset *)
Require Import List Multiset PermutSetoid Relations Sorting.
Section defs.
(** * Trees and heap trees *)
(** ** Definition of trees over an ordered set *)
Variable A : Type.
Variable leA : relation A.
Variable eqA : relation A.
Let gtA (x y:A) := ~ leA x y.
Hypothesis leA_dec : forall x y:A, {leA x y} + {leA y x}.
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
Hypothesis leA_refl : forall x y:A, eqA x y -> leA x y.
Hypothesis leA_trans : forall x y z:A, leA x y -> leA y z -> leA x z.
Hypothesis leA_antisym : forall x y:A, leA x y -> leA y x -> eqA x y.
Hint Resolve leA_refl.
Hint Immediate eqA_dec leA_dec leA_antisym.
Let emptyBag := EmptyBag A.
Let singletonBag := SingletonBag _ eqA_dec.
Inductive Tree :=
| Tree_Leaf : Tree
| Tree_Node : A -> Tree -> Tree -> Tree.
(** [a] is lower than a Tree [T] if [T] is a Leaf
or [T] is a Node holding [b>a] *)
Definition leA_Tree (a:A) (t:Tree) :=
match t with
| Tree_Leaf => True
| Tree_Node b T1 T2 => leA a b
end.
Lemma leA_Tree_Leaf : forall a:A, leA_Tree a Tree_Leaf.
Proof.
simpl; auto with datatypes.
Qed.
Lemma leA_Tree_Node :
forall (a b:A) (G D:Tree), leA a b -> leA_Tree a (Tree_Node b G D).
Proof.
simpl; auto with datatypes.
Qed.
(** ** The heap property *)
Inductive is_heap : Tree -> Prop :=
| nil_is_heap : is_heap Tree_Leaf
| node_is_heap :
forall (a:A) (T1 T2:Tree),
leA_Tree a T1 ->
leA_Tree a T2 ->
is_heap T1 -> is_heap T2 -> is_heap (Tree_Node a T1 T2).
Lemma invert_heap :
forall (a:A) (T1 T2:Tree),
is_heap (Tree_Node a T1 T2) ->
leA_Tree a T1 /\ leA_Tree a T2 /\ is_heap T1 /\ is_heap T2.
Proof.
intros; inversion H; auto with datatypes.
Qed.
(* This lemma ought to be generated automatically by the Inversion tools *)
Lemma is_heap_rect :
forall P:Tree -> Type,
P Tree_Leaf ->
(forall (a:A) (T1 T2:Tree),
leA_Tree a T1 ->
leA_Tree a T2 ->
is_heap T1 -> P T1 -> is_heap T2 -> P T2 -> P (Tree_Node a T1 T2)) ->
forall T:Tree, is_heap T -> P T.
Proof.
simple induction T; auto with datatypes.
intros a G PG D PD PN.
elim (invert_heap a G D); auto with datatypes.
intros H1 H2; elim H2; intros H3 H4; elim H4; intros.
apply X0; auto with datatypes.
Qed.
(* This lemma ought to be generated automatically by the Inversion tools *)
Lemma is_heap_rec :
forall P:Tree -> Set,
P Tree_Leaf ->
(forall (a:A) (T1 T2:Tree),
leA_Tree a T1 ->
leA_Tree a T2 ->
is_heap T1 -> P T1 -> is_heap T2 -> P T2 -> P (Tree_Node a T1 T2)) ->
forall T:Tree, is_heap T -> P T.
Proof.
simple induction T; auto with datatypes.
intros a G PG D PD PN.
elim (invert_heap a G D); auto with datatypes.
intros H1 H2; elim H2; intros H3 H4; elim H4; intros.
apply X; auto with datatypes.
Qed.
Lemma low_trans :
forall (T:Tree) (a b:A), leA a b -> leA_Tree b T -> leA_Tree a T.
Proof.
simple induction T; auto with datatypes.
intros; simpl; apply leA_trans with b; auto with datatypes.
Qed.
(** ** Merging two sorted lists *)
Inductive merge_lem (l1 l2:list A) : Type :=
merge_exist :
forall l:list A,
Sorted leA l ->
meq (list_contents _ eqA_dec l)
(munion (list_contents _ eqA_dec l1) (list_contents _ eqA_dec l2)) ->
(forall a, HdRel leA a l1 -> HdRel leA a l2 -> HdRel leA a l) ->
merge_lem l1 l2.
Require Import Morphisms.
Instance: Equivalence (@meq A).
Proof. constructor; auto with datatypes. red. apply meq_trans. Defined.
Instance: Proper (@meq A ++> @meq _ ++> @meq _) (@munion A).
Proof. intros x y H x' y' H'. now apply meq_congr. Qed.
Lemma merge :
forall l1:list A, Sorted leA l1 ->
forall l2:list A, Sorted leA l2 -> merge_lem l1 l2.
Proof.
fix 1; intros; destruct l1.
apply merge_exist with l2; auto with datatypes.
rename l1 into l.
revert l2 H0. fix 1. intros.
destruct l2 as [|a0 l0].
apply merge_exist with (a :: l); simpl; auto with datatypes.
elim (leA_dec a a0); intros.
(* 1 (leA a a0) *)
apply Sorted_inv in H. destruct H.
destruct (merge l H (a0 :: l0) H0).
apply merge_exist with (a :: l1). clear merge merge0.
auto using cons_sort, cons_leA with datatypes.
simpl. rewrite m. now rewrite munion_ass.
intros. apply cons_leA.
apply (@HdRel_inv _ leA) with l; trivial with datatypes.
(* 2 (leA a0 a) *)
apply Sorted_inv in H0. destruct H0.
destruct (merge0 l0 H0). clear merge merge0.
apply merge_exist with (a0 :: l1);
auto using cons_sort, cons_leA with datatypes.
simpl; rewrite m. simpl. setoid_rewrite munion_ass at 1. rewrite munion_comm.
repeat rewrite munion_ass. setoid_rewrite munion_comm at 3. reflexivity.
intros. apply cons_leA.
apply (@HdRel_inv _ leA) with l0; trivial with datatypes.
Qed.
(** ** From trees to multisets *)
(** contents of a tree as a multiset *)
(** Nota Bene : In what follows the definition of SingletonBag
in not used. Actually, we could just take as postulate:
[Parameter SingletonBag : A->multiset]. *)
Fixpoint contents (t:Tree) : multiset A :=
match t with
| Tree_Leaf => emptyBag
| Tree_Node a t1 t2 =>
munion (contents t1) (munion (contents t2) (singletonBag a))
end.
(** equivalence of two trees is equality of corresponding multisets *)
Definition equiv_Tree (t1 t2:Tree) := meq (contents t1) (contents t2).
(** * From lists to sorted lists *)
(** ** Specification of heap insertion *)
Inductive insert_spec (a:A) (T:Tree) : Type :=
insert_exist :
forall T1:Tree,
is_heap T1 ->
meq (contents T1) (munion (contents T) (singletonBag a)) ->
(forall b:A, leA b a -> leA_Tree b T -> leA_Tree b T1) ->
insert_spec a T.
Lemma insert : forall T:Tree, is_heap T -> forall a:A, insert_spec a T.
Proof.
simple induction 1; intros.
apply insert_exist with (Tree_Node a Tree_Leaf Tree_Leaf);
auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
simpl; unfold meq, munion; auto using node_is_heap with datatypes.
elim (leA_dec a a0); intros.
elim (X a0); intros.
apply insert_exist with (Tree_Node a T2 T0);
auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
simpl; apply treesort_twist1; trivial with datatypes.
elim (X a); intros T3 HeapT3 ConT3 LeA.
apply insert_exist with (Tree_Node a0 T2 T3);
auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
apply node_is_heap; auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
apply low_trans with a; auto with datatypes.
apply LeA; auto with datatypes.
apply low_trans with a; auto with datatypes.
simpl; apply treesort_twist2; trivial with datatypes.
Qed.
(** ** Building a heap from a list *)
Inductive build_heap (l:list A) : Type :=
heap_exist :
forall T:Tree,
is_heap T ->
meq (list_contents _ eqA_dec l) (contents T) -> build_heap l.
Lemma list_to_heap : forall l:list A, build_heap l.
Proof.
simple induction l.
apply (heap_exist nil Tree_Leaf); auto with datatypes.
simpl; unfold meq; exact nil_is_heap.
simple induction 1.
intros T i m; elim (insert T i a).
intros; apply heap_exist with T1; simpl; auto with datatypes.
apply meq_trans with (munion (contents T) (singletonBag a)).
apply meq_trans with (munion (singletonBag a) (contents T)).
apply meq_right; trivial with datatypes.
apply munion_comm.
apply meq_sym; trivial with datatypes.
Qed.
(** ** Building the sorted list *)
Inductive flat_spec (T:Tree) : Type :=
flat_exist :
forall l:list A,
Sorted leA l ->
(forall a:A, leA_Tree a T -> HdRel leA a l) ->
meq (contents T) (list_contents _ eqA_dec l) -> flat_spec T.
Lemma heap_to_list : forall T:Tree, is_heap T -> flat_spec T.
Proof.
intros T h; elim h; intros.
apply flat_exist with (nil (A:=A)); auto with datatypes.
elim X; intros l1 s1 i1 m1; elim X0; intros l2 s2 i2 m2.
elim (merge _ s1 _ s2); intros.
apply flat_exist with (a :: l); simpl; auto with datatypes.
apply meq_trans with
(munion (list_contents _ eqA_dec l1)
(munion (list_contents _ eqA_dec l2) (singletonBag a))).
apply meq_congr; auto with datatypes.
apply meq_trans with
(munion (singletonBag a)
(munion (list_contents _ eqA_dec l1) (list_contents _ eqA_dec l2))).
apply munion_rotate.
apply meq_right; apply meq_sym; trivial with datatypes.
Qed.
(** * Specification of treesort *)
Theorem treesort :
forall l:list A,
{m : list A | Sorted leA m & permutation _ eqA_dec l m}.
Proof.
intro l; unfold permutation.
elim (list_to_heap l).
intros.
elim (heap_to_list T); auto with datatypes.
intros.
exists l0; auto with datatypes.
apply meq_trans with (contents T); trivial with datatypes.
Qed.
End defs.

5944
samples/Coq/JsCorrectness.v Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,249 @@
Set Implicit Arguments.
Require Import JsSyntax JsInterpreterMonads JsInterpreter JsInit.
Require Import LibFix LibList.
Require Export Shared.
Require Export LibTactics LibLogic LibReflect LibList
LibOperation LibStruct LibNat LibEpsilon LibFunc LibHeap.
Require Flocq.Appli.Fappli_IEEE Flocq.Appli.Fappli_IEEE_bits.
(* Here stands some commands to extract relatively correctly the interpreter to Ocaml. *)
Extraction Language Ocaml.
Require Import ExtrOcamlBasic.
Require Import ExtrOcamlNatInt.
Require Import ExtrOcamlString.
(* Optimal fixpoint. *)
Extraction Inline FixFun3 FixFun3Mod FixFun4 FixFun4Mod FixFunMod curry3 uncurry3 curry4 uncurry4.
(* As classical logic statements are now unused, they should not be extracted
(otherwise, useless errors will be launched). *)
Extraction Inline epsilon epsilon_def classicT arbitrary indefinite_description Inhab_witness Fix isTrue.
(**************************************************************)
(** ** Numerical values *)
(* number *)
Extract Inductive positive => float
[ "(fun p -> 1. +. (2. *. p))"
"(fun p -> 2. *. p)"
"1." ]
"(fun f2p1 f2p f1 p ->
if p <= 1. then f1 () else if mod_float p 2. = 0. then f2p (floor (p /. 2.)) else f2p1 (floor (p /. 2.)))".
Extract Inductive Z => float [ "0." "" "(~-.)" ]
"(fun f0 fp fn z -> if z=0. then f0 () else if z>0. then fp z else fn (~-. z))".
Extract Inductive N => float [ "0." "" ]
"(fun f0 fp n -> if n=0. then f0 () else fp n)".
Extract Constant Z.add => "(+.)".
Extract Constant Z.succ => "(+.) 1.".
Extract Constant Z.pred => "(fun x -> x -. 1.)".
Extract Constant Z.sub => "(-.)".
Extract Constant Z.mul => "( *. )".
Extract Constant Z.opp => "(~-.)".
Extract Constant Z.abs => "abs_float".
Extract Constant Z.min => "min".
Extract Constant Z.max => "max".
Extract Constant Z.compare =>
"fun x y -> if x=y then Eq else if x<y then Lt else Gt".
Extract Constant Pos.add => "(+.)".
Extract Constant Pos.succ => "(+.) 1.".
Extract Constant Pos.pred => "(fun x -> x -. 1.)".
Extract Constant Pos.sub => "(-.)".
Extract Constant Pos.mul => "( *. )".
Extract Constant Pos.min => "min".
Extract Constant Pos.max => "max".
Extract Constant Pos.compare =>
"fun x y -> if x=y then Eq else if x<y then Lt else Gt".
Extract Constant Pos.compare_cont =>
"fun x y c -> if x=y then c else if x<y then Lt else Gt".
Extract Constant N.add => "(+.)".
Extract Constant N.succ => "(+.) 1.".
Extract Constant N.pred => "(fun x -> x -. 1.)".
Extract Constant N.sub => "(-.)".
Extract Constant N.mul => "( *. )".
Extract Constant N.min => "min".
Extract Constant N.max => "max".
Extract Constant N.div => "(fun x y -> if x = 0. then 0. else floor (x /. y))".
Extract Constant N.modulo => "mod_float".
Extract Constant N.compare =>
"fun x y -> if x=y then Eq else if x<y then Lt else Gt".
Extract Inductive Fappli_IEEE.binary_float => float [
"(fun s -> if s then (0.) else (-0.))"
"(fun s -> if s then infinity else neg_infinity)"
"nan"
"(fun (s, m, e) -> failwith ""FIXME: No extraction from binary float allowed yet."")"
].
Extract Constant JsNumber.of_int => "fun x -> x".
Extract Constant JsNumber.nan => "nan".
Extract Constant JsNumber.zero => "0.".
Extract Constant JsNumber.neg_zero => "(-0.)".
Extract Constant JsNumber.one => "1.".
Extract Constant JsNumber.infinity => "infinity".
Extract Constant JsNumber.neg_infinity => "neg_infinity".
Extract Constant JsNumber.max_value => "max_float".
Extract Constant JsNumber.min_value => "(Int64.float_of_bits Int64.one)".
Extract Constant JsNumber.pi => "(4. *. atan 1.)".
Extract Constant JsNumber.e => "(exp 1.)".
Extract Constant JsNumber.ln2 => "(log 2.)".
Extract Constant JsNumber.floor => "floor".
Extract Constant JsNumber.absolute => "abs_float".
Extract Constant JsNumber.from_string =>
"(fun s ->
try
let s = (String.concat """" (List.map (String.make 1) s)) in
if s = """" then 0. else float_of_string s
with Failure ""float_of_string"" -> nan)
(* Note that we're using `float_of_string' there, which does not have the same
behavior than JavaScript. For instance it will read ""022"" as 22 instead of
18, which should be the JavaScript result for it. *)".
Extract Constant JsNumber.to_string =>
"(fun f ->
prerr_string (""Warning: JsNumber.to_string called. This might be responsible for errors. Argument value: "" ^ string_of_float f ^ ""."");
prerr_newline();
let string_of_number n =
let sfn = string_of_float n in
(if (sfn = ""inf"") then ""Infinity"" else
if (sfn = ""-inf"") then ""-Infinity"" else
if (sfn = ""nan"") then ""NaN"" else
let inum = int_of_float n in
if (float_of_int inum = n) then (string_of_int inum) else (string_of_float n)) in
let ret = ref [] in (* Ugly, but the API for OCaml string is not very functional... *)
String.iter (fun c -> ret := c :: !ret) (string_of_number f);
List.rev !ret)
(* Note that this is ugly, we should use the spec of JsNumber.to_string here (9.8.1). *)".
Extract Constant JsNumber.add => "(+.)".
Extract Constant JsNumber.sub => "(-.)".
Extract Constant JsNumber.mult => "( *. )".
Extract Constant JsNumber.div => "(/.)".
Extract Constant JsNumber.fmod => "mod_float".
Extract Constant JsNumber.neg => "(~-.)".
Extract Constant JsNumber.sign => "(fun f -> float_of_int (compare f 0.))".
Extract Constant JsNumber.number_comparable => "(fun n1 n2 -> 0 = compare n1 n2)".
Extract Constant JsNumber.lt_bool => "(<)".
Extract Constant JsNumber.to_int32 =>
"fun n ->
match classify_float n with
| FP_normal | FP_subnormal ->
let i32 = 2. ** 32. in
let i31 = 2. ** 31. in
let posint = (if n < 0. then (-1.) else 1.) *. (floor (abs_float n)) in
let int32bit =
let smod = mod_float posint i32 in
if smod < 0. then smod +. i32 else smod
in
(if int32bit >= i31 then int32bit -. i32 else int32bit)
| _ -> 0.". (* LATER: do in Coq. Spec is 9.5, p. 47.*)
Extract Constant JsNumber.to_uint32 =>
"fun n ->
match classify_float n with
| FP_normal | FP_subnormal ->
let i32 = 2. ** 32. in
let posint = (if n < 0. then (-1.) else 1.) *. (floor (abs_float n)) in
let int32bit =
let smod = mod_float posint i32 in
if smod < 0. then smod +. i32 else smod
in
int32bit
| _ -> 0.". (* LAER: do in Coq. Spec is 9.6, p47.*)
Extract Constant JsNumber.modulo_32 => "(fun x -> let r = mod_float x 32. in if x < 0. then r +. 32. else r)".
Extract Constant JsNumber.int32_bitwise_not => "fun x -> Int32.to_float (Int32.lognot (Int32.of_float x))".
Extract Constant JsNumber.int32_bitwise_and => "fun x y -> Int32.to_float (Int32.logand (Int32.of_float x) (Int32.of_float y))".
Extract Constant JsNumber.int32_bitwise_or => "fun x y -> Int32.to_float (Int32.logor (Int32.of_float x) (Int32.of_float y))".
Extract Constant JsNumber.int32_bitwise_xor => "fun x y -> Int32.to_float (Int32.logxor (Int32.of_float x) (Int32.of_float y))".
Extract Constant JsNumber.int32_left_shift => "(fun x y -> Int32.to_float (Int32.shift_left (Int32.of_float x) (int_of_float y)))".
Extract Constant JsNumber.int32_right_shift => "(fun x y -> Int32.to_float (Int32.shift_right (Int32.of_float x) (int_of_float y)))".
Extract Constant JsNumber.uint32_right_shift =>
"(fun x y ->
let i31 = 2. ** 31. in
let i32 = 2. ** 32. in
let newx = if x >= i31 then x -. i32 else x in
let r = Int32.to_float (Int32.shift_right_logical (Int32.of_float newx) (int_of_float y)) in
if r < 0. then r +. i32 else r)".
Extract Constant int_of_char => "(fun c -> float_of_int (int_of_char c))".
Extract Constant ascii_comparable => "(=)".
Extract Constant lt_int_decidable => "(<)".
Extract Constant le_int_decidable => "(<=)".
Extract Constant ge_nat_decidable => "(>=)".
(* TODO ARTHUR: This TLC lemma does not extract to something computable... whereas it should! *)
Extract Constant prop_eq_decidable => "(=)".
Extract Constant env_loc_global_env_record => "0".
(* The following functions make pattern matches with floats and shall thus be removed. *)
Extraction Inline Fappli_IEEE.Bplus Fappli_IEEE.binary_normalize Fappli_IEEE_bits.b64_plus.
Extraction Inline Fappli_IEEE.Bmult Fappli_IEEE.Bmult_FF Fappli_IEEE_bits.b64_mult.
Extraction Inline Fappli_IEEE.Bdiv Fappli_IEEE_bits.b64_div.
(* New options for the interpreter to work in Coq 8.4 *)
Set Extraction AccessOpaque.
(* These parameters are implementation-dependant according to the spec.
I've chosed some very simple values, but we could choose another thing for them. *)
Extract Constant object_prealloc_global_proto => "(Coq_value_prim Coq_prim_null)".
Extract Constant object_prealloc_global_class => "(
let rec aux s = function
| 0 -> []
| n -> let n' = n - 1 in
s.[n'] :: aux s n'
in let aux2 s =
List.rev (aux s (String.length s))
in aux2 ""GlobalClass"")".
(* Parsing *)
Extract Constant parse_pickable => "(fun s strict ->
let str = String.concat """" (List.map (String.make 1) s) in
try
let parserExp = Parser_main.exp_from_string ~force_strict:strict str in
Some (JsSyntaxInfos.add_infos_prog strict
(Translate_syntax.exp_to_prog parserExp))
with
(* | Translate_syntax.CoqSyntaxDoesNotSupport _ -> assert false (* Temporary *) *)
| Parser.ParserFailure _
| Parser.InvalidArgument ->
prerr_string (""Warning: Parser error on eval. Input string: \"""" ^ str ^ ""\""\n"");
None
)".
(* Debugging *)
Extract Inlined Constant not_yet_implemented_because => "(fun s ->
print_endline (__LOC__ ^ "": Not implemented because: "" ^ Prheap.string_of_char_list s) ;
Coq_result_not_yet_implemented)".
Extract Inlined Constant impossible_because => "(fun s ->
print_endline (__LOC__ ^ "": Stuck because: "" ^ Prheap.string_of_char_list s) ;
Coq_result_impossible)".
Extract Inlined Constant impossible_with_heap_because => "(fun s message ->
print_endline (__LOC__ ^ "": Stuck!\nState: "" ^ Prheap.prstate true s
^ ""\nMessage:\t"" ^ Prheap.string_of_char_list message) ;
Coq_result_impossible)".
(* Final Extraction *)
Extraction Blacklist string list bool.
Separate Extraction runs run_javascript.
(* -- LATER: extract inequality_test_string in more efficient way*)

1051
samples/Coq/JsNumber.v Normal file

File diff suppressed because it is too large Load Diff

1766
samples/Coq/JsPrettyInterm.v Normal file

File diff suppressed because it is too large Load Diff

42
samples/Coq/Main.v Normal file
View File

@@ -0,0 +1,42 @@
Require Import FunctionNinjas.All.
Require Import ListString.All.
Require Import Computation.
Import C.Notations.
Definition error (message : LString.t) : C.t :=
do_call! Command.ShowError message in
ret.
Definition main : C.t :=
call! card_is_valid := Command.AskCard in
if card_is_valid then
call! pin := Command.AskPIN in
match pin with
| None => error @@ LString.s "No PIN given."
| Some pin =>
call! pin_is_valid := Command.CheckPIN pin in
if pin_is_valid then
call! ask_amount := Command.AskAmount in
match ask_amount with
| None => error @@ LString.s "No amount given."
| Some amount =>
call! amount_is_valid := Command.CheckAmount amount in
if amount_is_valid then
call! card_is_given := Command.GiveCard in
if card_is_given then
call! amount_is_given := Command.GiveAmount amount in
if amount_is_given then
ret
else
error @@ LString.s "Cannot give you the amount. Please contact your bank."
else
error @@ LString.s "Cannot give you back the card. Please contact your bank."
else
error @@ LString.s "Invalid amount."
end
else
error @@ LString.s "Invalid PIN."
end
else
error @@ LString.s "Invalid card.".

View File

@@ -1,539 +0,0 @@
Require Import Omega Relations Multiset SetoidList.
(** This file is deprecated, use [Permutation.v] instead.
Indeed, this file defines a notion of permutation based on
multisets (there exists a permutation between two lists iff every
elements have the same multiplicity in the two lists) which
requires a more complex apparatus (the equipment of the domain
with a decidable equality) than [Permutation] in [Permutation.v].
The relation between the two relations are in lemma
[permutation_Permutation].
File [Permutation] concerns Leibniz equality : it shows in particular
that [List.Permutation] and [permutation] are equivalent in this context.
*)
Set Implicit Arguments.
Local Notation "[ ]" := nil.
Local Notation "[ a ; .. ; b ]" := (a :: .. (b :: []) ..).
Section Permut.
(** * From lists to multisets *)
Variable A : Type.
Variable eqA : relation A.
Hypothesis eqA_equiv : Equivalence eqA.
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
Let emptyBag := EmptyBag A.
Let singletonBag := SingletonBag _ eqA_dec.
(** contents of a list *)
Fixpoint list_contents (l:list A) : multiset A :=
match l with
| [] => emptyBag
| a :: l => munion (singletonBag a) (list_contents l)
end.
Lemma list_contents_app :
forall l m:list A,
meq (list_contents (l ++ m)) (munion (list_contents l) (list_contents m)).
Proof.
simple induction l; simpl; auto with datatypes.
intros.
apply meq_trans with
(munion (singletonBag a) (munion (list_contents l0) (list_contents m)));
auto with datatypes.
Qed.
(** * [permutation]: definition and basic properties *)
Definition permutation (l m:list A) := meq (list_contents l) (list_contents m).
Lemma permut_refl : forall l:list A, permutation l l.
Proof.
unfold permutation; auto with datatypes.
Qed.
Lemma permut_sym :
forall l1 l2 : list A, permutation l1 l2 -> permutation l2 l1.
Proof.
unfold permutation, meq; intros; symmetry; trivial.
Qed.
Lemma permut_trans :
forall l m n:list A, permutation l m -> permutation m n -> permutation l n.
Proof.
unfold permutation; intros.
apply meq_trans with (list_contents m); auto with datatypes.
Qed.
Lemma permut_cons_eq :
forall l m:list A,
permutation l m -> forall a a', eqA a a' -> permutation (a :: l) (a' :: m).
Proof.
unfold permutation; simpl; intros.
apply meq_trans with (munion (singletonBag a') (list_contents l)).
apply meq_left, meq_singleton; auto.
auto with datatypes.
Qed.
Lemma permut_cons :
forall l m:list A,
permutation l m -> forall a:A, permutation (a :: l) (a :: m).
Proof.
unfold permutation; simpl; auto with datatypes.
Qed.
Lemma permut_app :
forall l l' m m':list A,
permutation l l' -> permutation m m' -> permutation (l ++ m) (l' ++ m').
Proof.
unfold permutation; intros.
apply meq_trans with (munion (list_contents l) (list_contents m));
auto using permut_cons, list_contents_app with datatypes.
apply meq_trans with (munion (list_contents l') (list_contents m'));
auto using permut_cons, list_contents_app with datatypes.
apply meq_trans with (munion (list_contents l') (list_contents m));
auto using permut_cons, list_contents_app with datatypes.
Qed.
Lemma permut_add_inside_eq :
forall a a' l1 l2 l3 l4, eqA a a' ->
permutation (l1 ++ l2) (l3 ++ l4) ->
permutation (l1 ++ a :: l2) (l3 ++ a' :: l4).
Proof.
unfold permutation, meq in *; intros.
specialize H0 with a0.
repeat rewrite list_contents_app in *; simpl in *.
destruct (eqA_dec a a0) as [Ha|Ha]; rewrite H in Ha;
decide (eqA_dec a' a0) with Ha; simpl; auto with arith.
do 2 rewrite <- plus_n_Sm; f_equal; auto.
Qed.
Lemma permut_add_inside :
forall a l1 l2 l3 l4,
permutation (l1 ++ l2) (l3 ++ l4) ->
permutation (l1 ++ a :: l2) (l3 ++ a :: l4).
Proof.
unfold permutation, meq in *; intros.
generalize (H a0); clear H.
do 4 rewrite list_contents_app.
simpl.
destruct (eqA_dec a a0); simpl; auto with arith.
do 2 rewrite <- plus_n_Sm; f_equal; auto.
Qed.
Lemma permut_add_cons_inside_eq :
forall a a' l l1 l2, eqA a a' ->
permutation l (l1 ++ l2) ->
permutation (a :: l) (l1 ++ a' :: l2).
Proof.
intros;
replace (a :: l) with ([] ++ a :: l); trivial;
apply permut_add_inside_eq; trivial.
Qed.
Lemma permut_add_cons_inside :
forall a l l1 l2,
permutation l (l1 ++ l2) ->
permutation (a :: l) (l1 ++ a :: l2).
Proof.
intros;
replace (a :: l) with ([] ++ a :: l); trivial;
apply permut_add_inside; trivial.
Qed.
Lemma permut_middle :
forall (l m:list A) (a:A), permutation (a :: l ++ m) (l ++ a :: m).
Proof.
intros; apply permut_add_cons_inside; auto using permut_sym, permut_refl.
Qed.
Lemma permut_sym_app :
forall l1 l2, permutation (l1 ++ l2) (l2 ++ l1).
Proof.
intros l1 l2;
unfold permutation, meq;
intro a; do 2 rewrite list_contents_app; simpl;
auto with arith.
Qed.
Lemma permut_rev :
forall l, permutation l (rev l).
Proof.
induction l.
simpl; trivial using permut_refl.
simpl.
apply permut_add_cons_inside.
rewrite <- app_nil_end. trivial.
Qed.
(** * Some inversion results. *)
Lemma permut_conv_inv :
forall e l1 l2, permutation (e :: l1) (e :: l2) -> permutation l1 l2.
Proof.
intros e l1 l2; unfold permutation, meq; simpl; intros H a;
generalize (H a); apply plus_reg_l.
Qed.
Lemma permut_app_inv1 :
forall l l1 l2, permutation (l1 ++ l) (l2 ++ l) -> permutation l1 l2.
Proof.
intros l l1 l2; unfold permutation, meq; simpl;
intros H a; generalize (H a); clear H.
do 2 rewrite list_contents_app.
simpl.
intros; apply plus_reg_l with (multiplicity (list_contents l) a).
rewrite plus_comm; rewrite H; rewrite plus_comm.
trivial.
Qed.
(** we can use [multiplicity] to define [InA] and [NoDupA]. *)
Fact if_eqA_then : forall a a' (B:Type)(b b':B),
eqA a a' -> (if eqA_dec a a' then b else b') = b.
Proof.
intros. destruct eqA_dec as [_|NEQ]; auto.
contradict NEQ; auto.
Qed.
Lemma permut_app_inv2 :
forall l l1 l2, permutation (l ++ l1) (l ++ l2) -> permutation l1 l2.
Proof.
intros l l1 l2; unfold permutation, meq; simpl;
intros H a; generalize (H a); clear H.
do 2 rewrite list_contents_app.
simpl.
intros; apply plus_reg_l with (multiplicity (list_contents l) a).
trivial.
Qed.
Lemma permut_remove_hd_eq :
forall l l1 l2 a b, eqA a b ->
permutation (a :: l) (l1 ++ b :: l2) -> permutation l (l1 ++ l2).
Proof.
unfold permutation, meq; simpl; intros l l1 l2 a b Heq H a0.
specialize H with a0.
rewrite list_contents_app in *; simpl in *.
apply plus_reg_l with (if eqA_dec a a0 then 1 else 0).
rewrite H; clear H.
symmetry; rewrite plus_comm, <- ! plus_assoc; f_equal.
rewrite plus_comm.
destruct (eqA_dec a a0) as [Ha|Ha]; rewrite Heq in Ha;
decide (eqA_dec b a0) with Ha; reflexivity.
Qed.
Lemma permut_remove_hd :
forall l l1 l2 a,
permutation (a :: l) (l1 ++ a :: l2) -> permutation l (l1 ++ l2).
Proof.
eauto using permut_remove_hd_eq, Equivalence_Reflexive.
Qed.
Fact if_eqA_else : forall a a' (B:Type)(b b':B),
~eqA a a' -> (if eqA_dec a a' then b else b') = b'.
Proof.
intros. decide (eqA_dec a a') with H; auto.
Qed.
Fact if_eqA_refl : forall a (B:Type)(b b':B),
(if eqA_dec a a then b else b') = b.
Proof.
intros; apply (decide_left (eqA_dec a a)); auto with *.
Qed.
(** PL: Inutilisable dans un rewrite sans un change prealable. *)
Global Instance if_eqA (B:Type)(b b':B) :
Proper (eqA==>eqA==>@eq _) (fun x y => if eqA_dec x y then b else b').
Proof.
intros x x' Hxx' y y' Hyy'.
intros; destruct (eqA_dec x y) as [H|H];
destruct (eqA_dec x' y') as [H'|H']; auto.
contradict H'; transitivity x; auto with *; transitivity y; auto with *.
contradict H; transitivity x'; auto with *; transitivity y'; auto with *.
Qed.
Fact if_eqA_rewrite_l : forall a1 a1' a2 (B:Type)(b b':B),
eqA a1 a1' -> (if eqA_dec a1 a2 then b else b') =
(if eqA_dec a1' a2 then b else b').
Proof.
intros; destruct (eqA_dec a1 a2) as [A1|A1];
destruct (eqA_dec a1' a2) as [A1'|A1']; auto.
contradict A1'; transitivity a1; eauto with *.
contradict A1; transitivity a1'; eauto with *.
Qed.
Fact if_eqA_rewrite_r : forall a1 a2 a2' (B:Type)(b b':B),
eqA a2 a2' -> (if eqA_dec a1 a2 then b else b') =
(if eqA_dec a1 a2' then b else b').
Proof.
intros; destruct (eqA_dec a1 a2) as [A2|A2];
destruct (eqA_dec a1 a2') as [A2'|A2']; auto.
contradict A2'; transitivity a2; eauto with *.
contradict A2; transitivity a2'; eauto with *.
Qed.
Global Instance multiplicity_eqA (l:list A) :
Proper (eqA==>@eq _) (multiplicity (list_contents l)).
Proof.
intros x x' Hxx'.
induction l as [|y l Hl]; simpl; auto.
rewrite (@if_eqA_rewrite_r y x x'); auto.
Qed.
Lemma multiplicity_InA :
forall l a, InA eqA a l <-> 0 < multiplicity (list_contents l) a.
Proof.
induction l.
simpl.
split; inversion 1.
simpl.
intros a'; split; intros H. inversion_clear H.
apply (decide_left (eqA_dec a a')); auto with *.
destruct (eqA_dec a a'); auto with *. simpl; rewrite <- IHl; auto.
destruct (eqA_dec a a'); auto with *. right. rewrite IHl; auto.
Qed.
Lemma multiplicity_InA_O :
forall l a, ~ InA eqA a l -> multiplicity (list_contents l) a = 0.
Proof.
intros l a; rewrite multiplicity_InA;
destruct (multiplicity (list_contents l) a); auto with arith.
destruct 1; auto with arith.
Qed.
Lemma multiplicity_InA_S :
forall l a, InA eqA a l -> multiplicity (list_contents l) a >= 1.
Proof.
intros l a; rewrite multiplicity_InA; auto with arith.
Qed.
Lemma multiplicity_NoDupA : forall l,
NoDupA eqA l <-> (forall a, multiplicity (list_contents l) a <= 1).
Proof.
induction l.
simpl.
split; auto with arith.
split; simpl.
inversion_clear 1.
rewrite IHl in H1.
intros; destruct (eqA_dec a a0) as [EQ|NEQ]; simpl; auto with *.
rewrite <- EQ.
rewrite multiplicity_InA_O; auto.
intros; constructor.
rewrite multiplicity_InA.
specialize (H a).
rewrite if_eqA_refl in H.
clear IHl; omega.
rewrite IHl; intros.
specialize (H a0). omega.
Qed.
(** Permutation is compatible with InA. *)
Lemma permut_InA_InA :
forall l1 l2 e, permutation l1 l2 -> InA eqA e l1 -> InA eqA e l2.
Proof.
intros l1 l2 e.
do 2 rewrite multiplicity_InA.
unfold permutation, meq.
intros H;rewrite H; auto.
Qed.
Lemma permut_cons_InA :
forall l1 l2 e, permutation (e :: l1) l2 -> InA eqA e l2.
Proof.
intros; apply (permut_InA_InA (e:=e) H); auto with *.
Qed.
(** Permutation of an empty list. *)
Lemma permut_nil :
forall l, permutation l [] -> l = [].
Proof.
intro l; destruct l as [ | e l ]; trivial.
assert (InA eqA e (e::l)) by (auto with *).
intro Abs; generalize (permut_InA_InA Abs H).
inversion 1.
Qed.
(** Permutation for short lists. *)
Lemma permut_length_1:
forall a b, permutation [a] [b] -> eqA a b.
Proof.
intros a b; unfold permutation, meq.
intro P; specialize (P b); simpl in *.
rewrite if_eqA_refl in *.
destruct (eqA_dec a b); simpl; auto; discriminate.
Qed.
Lemma permut_length_2 :
forall a1 b1 a2 b2, permutation [a1; b1] [a2; b2] ->
(eqA a1 a2) /\ (eqA b1 b2) \/ (eqA a1 b2) /\ (eqA a2 b1).
Proof.
intros a1 b1 a2 b2 P.
assert (H:=permut_cons_InA P).
inversion_clear H.
left; split; auto.
apply permut_length_1.
red; red; intros.
specialize (P a). simpl in *.
rewrite (@if_eqA_rewrite_l a1 a2 a) in P by auto. omega.
right.
inversion_clear H0; [|inversion H].
split; auto.
apply permut_length_1.
red; red; intros.
specialize (P a); simpl in *.
rewrite (@if_eqA_rewrite_l a1 b2 a) in P by auto. omega.
Qed.
(** Permutation is compatible with length. *)
Lemma permut_length :
forall l1 l2, permutation l1 l2 -> length l1 = length l2.
Proof.
induction l1; intros l2 H.
rewrite (permut_nil (permut_sym H)); auto.
assert (H0:=permut_cons_InA H).
destruct (InA_split H0) as (h2,(b,(t2,(H1,H2)))).
subst l2.
rewrite app_length.
simpl; rewrite <- plus_n_Sm; f_equal.
rewrite <- app_length.
apply IHl1.
apply permut_remove_hd with b.
apply permut_trans with (a::l1); auto.
revert H1; unfold permutation, meq; simpl.
intros; f_equal; auto.
rewrite (@if_eqA_rewrite_l a b a0); auto.
Qed.
Lemma NoDupA_equivlistA_permut :
forall l l', NoDupA eqA l -> NoDupA eqA l' ->
equivlistA eqA l l' -> permutation l l'.
Proof.
intros.
red; unfold meq; intros.
rewrite multiplicity_NoDupA in H, H0.
generalize (H a) (H0 a) (H1 a); clear H H0 H1.
do 2 rewrite multiplicity_InA.
destruct 3; omega.
Qed.
End Permut.
Section Permut_map.
Variables A B : Type.
Variable eqA : relation A.
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
Hypothesis eqA_equiv : Equivalence eqA.
Variable eqB : B->B->Prop.
Hypothesis eqB_dec : forall x y:B, { eqB x y }+{ ~eqB x y }.
Hypothesis eqB_trans : Transitive eqB.
(** Permutation is compatible with map. *)
Lemma permut_map :
forall f,
(Proper (eqA==>eqB) f) ->
forall l1 l2, permutation _ eqA_dec l1 l2 ->
permutation _ eqB_dec (map f l1) (map f l2).
Proof.
intros f; induction l1.
intros l2 P; rewrite (permut_nil eqA_equiv (permut_sym P)); apply permut_refl.
intros l2 P.
simpl.
assert (H0:=permut_cons_InA eqA_equiv P).
destruct (InA_split H0) as (h2,(b,(t2,(H1,H2)))).
subst l2.
rewrite map_app.
simpl.
apply permut_trans with (f b :: map f l1).
revert H1; unfold permutation, meq; simpl.
intros; f_equal; auto.
destruct (eqB_dec (f b) a0) as [H2|H2];
destruct (eqB_dec (f a) a0) as [H3|H3]; auto.
destruct H3; transitivity (f b); auto with *.
destruct H2; transitivity (f a); auto with *.
apply permut_add_cons_inside.
rewrite <- map_app.
apply IHl1; auto.
apply permut_remove_hd with b; trivial.
apply permut_trans with (a::l1); auto.
revert H1; unfold permutation, meq; simpl.
intros; f_equal; auto.
rewrite (@if_eqA_rewrite_l _ _ eqA_equiv eqA_dec a b a0); auto.
Qed.
End Permut_map.
Require Import Permutation.
Section Permut_permut.
Variable A : Type.
Variable eqA : relation A.
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
Hypothesis eqA_equiv : Equivalence eqA.
Lemma Permutation_impl_permutation : forall l l',
Permutation l l' -> permutation _ eqA_dec l l'.
Proof.
induction 1.
apply permut_refl.
apply permut_cons; auto using Equivalence_Reflexive.
change (x :: y :: l) with ([x] ++ y :: l);
apply permut_add_cons_inside; simpl;
apply permut_cons_eq; auto using Equivalence_Reflexive, permut_refl.
apply permut_trans with l'; trivial.
Qed.
Lemma permut_eqA : forall l l', Forall2 eqA l l' -> permutation _ eqA_dec l l'.
Proof.
induction 1.
apply permut_refl.
apply permut_cons_eq; trivial.
Qed.
Lemma permutation_Permutation : forall l l',
permutation _ eqA_dec l l' <->
exists l'', Permutation l l'' /\ Forall2 eqA l'' l'.
Proof.
split; intro H.
(* -> *)
induction l in l', H |- *.
exists []; apply permut_sym, permut_nil in H as ->; auto using Forall2.
pose proof H as H'.
apply permut_cons_InA, InA_split in H
as (l1 & y & l2 & Heq & ->); trivial.
apply permut_remove_hd_eq, IHl in H'
as (l'' & IHP & IHA); clear IHl; trivial.
apply Forall2_app_inv_r in IHA as (l1'' & l2'' & Hl1 & Hl2 & ->).
exists (l1'' ++ a :: l2''); split.
apply Permutation_cons_app; trivial.
apply Forall2_app, Forall2_cons; trivial.
(* <- *)
destruct H as (l'' & H & Heq).
apply permut_trans with l''.
apply Permutation_impl_permutation; trivial.
apply permut_eqA; trivial.
Qed.
End Permut_permut.
(* begin hide *)
(** For compatibilty *)
Notation permut_right := permut_cons (only parsing).
Notation permut_tran := permut_trans (only parsing).
(* end hide *)

View File

@@ -1,632 +0,0 @@
(* Adapted in May 2006 by Jean-Marc Notin from initial contents by
Laurent Thery (Huffmann contribution, October 2003) *)
Require Import List Setoid Compare_dec Morphisms.
Import ListNotations. (* For notations [] and [a;b;c] *)
Set Implicit Arguments.
Section Permutation.
Variable A:Type.
Inductive Permutation : list A -> list A -> Prop :=
| perm_nil: Permutation [] []
| perm_skip x l l' : Permutation l l' -> Permutation (x::l) (x::l')
| perm_swap x y l : Permutation (y::x::l) (x::y::l)
| perm_trans l l' l'' :
Permutation l l' -> Permutation l' l'' -> Permutation l l''.
Local Hint Constructors Permutation.
(** Some facts about [Permutation] *)
Theorem Permutation_nil : forall (l : list A), Permutation [] l -> l = [].
Proof.
intros l HF.
remember (@nil A) as m in HF.
induction HF; discriminate || auto.
Qed.
Theorem Permutation_nil_cons : forall (l : list A) (x : A),
~ Permutation nil (x::l).
Proof.
intros l x HF.
apply Permutation_nil in HF; discriminate.
Qed.
(** Permutation over lists is a equivalence relation *)
Theorem Permutation_refl : forall l : list A, Permutation l l.
Proof.
induction l; constructor. exact IHl.
Qed.
Theorem Permutation_sym : forall l l' : list A,
Permutation l l' -> Permutation l' l.
Proof.
intros l l' Hperm; induction Hperm; auto.
apply perm_trans with (l':=l'); assumption.
Qed.
Theorem Permutation_trans : forall l l' l'' : list A,
Permutation l l' -> Permutation l' l'' -> Permutation l l''.
Proof.
exact perm_trans.
Qed.
End Permutation.
Hint Resolve Permutation_refl perm_nil perm_skip.
(* These hints do not reduce the size of the problem to solve and they
must be used with care to avoid combinatoric explosions *)
Local Hint Resolve perm_swap perm_trans.
Local Hint Resolve Permutation_sym Permutation_trans.
(* This provides reflexivity, symmetry and transitivity and rewriting
on morphims to come *)
Instance Permutation_Equivalence A : Equivalence (@Permutation A) | 10 := {
Equivalence_Reflexive := @Permutation_refl A ;
Equivalence_Symmetric := @Permutation_sym A ;
Equivalence_Transitive := @Permutation_trans A }.
Instance Permutation_cons A :
Proper (Logic.eq ==> @Permutation A ==> @Permutation A) (@cons A) | 10.
Proof.
repeat intro; subst; auto using perm_skip.
Qed.
Section Permutation_properties.
Variable A:Type.
Implicit Types a b : A.
Implicit Types l m : list A.
(** Compatibility with others operations on lists *)
Theorem Permutation_in : forall (l l' : list A) (x : A),
Permutation l l' -> In x l -> In x l'.
Proof.
intros l l' x Hperm; induction Hperm; simpl; tauto.
Qed.
Global Instance Permutation_in' :
Proper (Logic.eq ==> @Permutation A ==> iff) (@In A) | 10.
Proof.
repeat red; intros; subst; eauto using Permutation_in.
Qed.
Lemma Permutation_app_tail : forall (l l' tl : list A),
Permutation l l' -> Permutation (l++tl) (l'++tl).
Proof.
intros l l' tl Hperm; induction Hperm as [|x l l'|x y l|l l' l'']; simpl; auto.
eapply Permutation_trans with (l':=l'++tl); trivial.
Qed.
Lemma Permutation_app_head : forall (l tl tl' : list A),
Permutation tl tl' -> Permutation (l++tl) (l++tl').
Proof.
intros l tl tl' Hperm; induction l;
[trivial | repeat rewrite <- app_comm_cons; constructor; assumption].
Qed.
Theorem Permutation_app : forall (l m l' m' : list A),
Permutation l l' -> Permutation m m' -> Permutation (l++m) (l'++m').
Proof.
intros l m l' m' Hpermll' Hpermmm';
induction Hpermll' as [|x l l'|x y l|l l' l''];
repeat rewrite <- app_comm_cons; auto.
apply Permutation_trans with (l' := (x :: y :: l ++ m));
[idtac | repeat rewrite app_comm_cons; apply Permutation_app_head]; trivial.
apply Permutation_trans with (l' := (l' ++ m')); try assumption.
apply Permutation_app_tail; assumption.
Qed.
Global Instance Permutation_app' :
Proper (@Permutation A ==> @Permutation A ==> @Permutation A) (@app A) | 10.
Proof.
repeat intro; now apply Permutation_app.
Qed.
Lemma Permutation_add_inside : forall a (l l' tl tl' : list A),
Permutation l l' -> Permutation tl tl' ->
Permutation (l ++ a :: tl) (l' ++ a :: tl').
Proof.
intros; apply Permutation_app; auto.
Qed.
Lemma Permutation_cons_append : forall (l : list A) x,
Permutation (x :: l) (l ++ x :: nil).
Proof. induction l; intros; auto. simpl. rewrite <- IHl; auto. Qed.
Local Hint Resolve Permutation_cons_append.
Theorem Permutation_app_comm : forall (l l' : list A),
Permutation (l ++ l') (l' ++ l).
Proof.
induction l as [|x l]; simpl; intro l'.
rewrite app_nil_r; trivial. rewrite IHl.
rewrite app_comm_cons, Permutation_cons_append.
now rewrite <- app_assoc.
Qed.
Local Hint Resolve Permutation_app_comm.
Theorem Permutation_cons_app : forall (l l1 l2:list A) a,
Permutation l (l1 ++ l2) -> Permutation (a :: l) (l1 ++ a :: l2).
Proof.
intros l l1 l2 a H. rewrite H.
rewrite app_comm_cons, Permutation_cons_append.
now rewrite <- app_assoc.
Qed.
Local Hint Resolve Permutation_cons_app.
Theorem Permutation_middle : forall (l1 l2:list A) a,
Permutation (a :: l1 ++ l2) (l1 ++ a :: l2).
Proof.
auto.
Qed.
Local Hint Resolve Permutation_middle.
Theorem Permutation_rev : forall (l : list A), Permutation l (rev l).
Proof.
induction l as [| x l]; simpl; trivial. now rewrite IHl at 1.
Qed.
Global Instance Permutation_rev' :
Proper (@Permutation A ==> @Permutation A) (@rev A) | 10.
Proof.
repeat intro; now rewrite <- 2 Permutation_rev.
Qed.
Theorem Permutation_length : forall (l l' : list A),
Permutation l l' -> length l = length l'.
Proof.
intros l l' Hperm; induction Hperm; simpl; auto. now transitivity (length l').
Qed.
Global Instance Permutation_length' :
Proper (@Permutation A ==> Logic.eq) (@length A) | 10.
Proof.
exact Permutation_length.
Qed.
Theorem Permutation_ind_bis :
forall P : list A -> list A -> Prop,
P [] [] ->
(forall x l l', Permutation l l' -> P l l' -> P (x :: l) (x :: l')) ->
(forall x y l l', Permutation l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')) ->
(forall l l' l'', Permutation l l' -> P l l' -> Permutation l' l'' -> P l' l'' -> P l l'') ->
forall l l', Permutation l l' -> P l l'.
Proof.
intros P Hnil Hskip Hswap Htrans.
induction 1; auto.
apply Htrans with (x::y::l); auto.
apply Hswap; auto.
induction l; auto.
apply Hskip; auto.
apply Hskip; auto.
induction l; auto.
eauto.
Qed.
Ltac break_list l x l' H :=
destruct l as [|x l']; simpl in *;
injection H; intros; subst; clear H.
Theorem Permutation_nil_app_cons : forall (l l' : list A) (x : A),
~ Permutation nil (l++x::l').
Proof.
intros l l' x HF.
apply Permutation_nil in HF. destruct l; discriminate.
Qed.
Theorem Permutation_app_inv : forall (l1 l2 l3 l4:list A) a,
Permutation (l1++a::l2) (l3++a::l4) -> Permutation (l1++l2) (l3 ++ l4).
Proof.
intros l1 l2 l3 l4 a; revert l1 l2 l3 l4.
set (P l l' :=
forall l1 l2 l3 l4, l=l1++a::l2 -> l'=l3++a::l4 ->
Permutation (l1++l2) (l3++l4)).
cut (forall l l', Permutation l l' -> P l l').
intros H; intros; eapply H; eauto.
apply (Permutation_ind_bis P); unfold P; clear P.
- (* nil *)
intros; now destruct l1.
- (* skip *)
intros x l l' H IH; intros.
break_list l1 b l1' H0; break_list l3 c l3' H1.
auto.
now rewrite H.
now rewrite <- H.
now rewrite (IH _ _ _ _ eq_refl eq_refl).
- (* swap *)
intros x y l l' Hp IH; intros.
break_list l1 b l1' H; break_list l3 c l3' H0.
auto.
break_list l3' b l3'' H.
auto.
constructor. now rewrite Permutation_middle.
break_list l1' c l1'' H1.
auto.
constructor. now rewrite Permutation_middle.
break_list l3' d l3'' H; break_list l1' e l1'' H1.
auto.
rewrite perm_swap. constructor. now rewrite Permutation_middle.
rewrite perm_swap. constructor. now rewrite Permutation_middle.
now rewrite perm_swap, (IH _ _ _ _ eq_refl eq_refl).
- (*trans*)
intros.
destruct (In_split a l') as (l'1,(l'2,H6)).
rewrite <- H.
subst l.
apply in_or_app; right; red; auto.
apply perm_trans with (l'1++l'2).
apply (H0 _ _ _ _ H3 H6).
apply (H2 _ _ _ _ H6 H4).
Qed.
Theorem Permutation_cons_inv l l' a :
Permutation (a::l) (a::l') -> Permutation l l'.
Proof.
intro H; exact (Permutation_app_inv [] l [] l' a H).
Qed.
Theorem Permutation_cons_app_inv l l1 l2 a :
Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2).
Proof.
intro H; exact (Permutation_app_inv [] l l1 l2 a H).
Qed.
Theorem Permutation_app_inv_l : forall l l1 l2,
Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2.
Proof.
induction l; simpl; auto.
intros.
apply IHl.
apply Permutation_cons_inv with a; auto.
Qed.
Theorem Permutation_app_inv_r : forall l l1 l2,
Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2.
Proof.
induction l.
intros l1 l2; do 2 rewrite app_nil_r; auto.
intros.
apply IHl.
apply Permutation_app_inv with a; auto.
Qed.
Lemma Permutation_length_1_inv: forall a l, Permutation [a] l -> l = [a].
Proof.
intros a l H; remember [a] as m in H.
induction H; try (injection Heqm as -> ->; clear Heqm);
discriminate || auto.
apply Permutation_nil in H as ->; trivial.
Qed.
Lemma Permutation_length_1: forall a b, Permutation [a] [b] -> a = b.
Proof.
intros a b H.
apply Permutation_length_1_inv in H; injection H as ->; trivial.
Qed.
Lemma Permutation_length_2_inv :
forall a1 a2 l, Permutation [a1;a2] l -> l = [a1;a2] \/ l = [a2;a1].
Proof.
intros a1 a2 l H; remember [a1;a2] as m in H.
revert a1 a2 Heqm.
induction H; intros; try (injection Heqm; intros; subst; clear Heqm);
discriminate || (try tauto).
apply Permutation_length_1_inv in H as ->; left; auto.
apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as ();
auto.
Qed.
Lemma Permutation_length_2 :
forall a1 a2 b1 b2, Permutation [a1;a2] [b1;b2] ->
a1 = b1 /\ a2 = b2 \/ a1 = b2 /\ a2 = b1.
Proof.
intros a1 b1 a2 b2 H.
apply Permutation_length_2_inv in H as [H|H]; injection H as -> ->; auto.
Qed.
Let in_middle l l1 l2 (a:A) : l = l1 ++ a :: l2 ->
forall x, In x l <-> a = x \/ In x (l1++l2).
Proof.
intros; subst; rewrite !in_app_iff; simpl. tauto.
Qed.
Lemma NoDup_cardinal_incl (l l' : list A) : NoDup l -> NoDup l' ->
length l = length l' -> incl l l' -> incl l' l.
Proof.
intros N. revert l'. induction N as [|a l Hal Hl IH].
- destruct l'; now auto.
- intros l' Hl' E H x Hx.
assert (Ha : In a l') by (apply H; simpl; auto).
destruct (in_split _ _ Ha) as (l1 & l2 & H12). clear Ha.
rewrite in_middle in Hx; eauto.
destruct Hx as [Hx|Hx]; [left|right]; auto.
apply (IH (l1++l2)); auto.
* apply NoDup_remove_1 with a; rewrite <- H12; auto.
* apply eq_add_S.
simpl in E; rewrite E, H12, !app_length; simpl; auto with arith.
* intros y Hy. assert (Hy' : In y l') by (apply H; simpl; auto).
rewrite in_middle in Hy'; eauto.
destruct Hy'; auto. subst y; intuition.
Qed.
Lemma NoDup_Permutation l l' : NoDup l -> NoDup l' ->
(forall x:A, In x l <-> In x l') -> Permutation l l'.
Proof.
intros N. revert l'. induction N as [|a l Hal Hl IH].
- destruct l'; simpl; auto.
intros Hl' H. exfalso. rewrite (H a); auto.
- intros l' Hl' H.
assert (Ha : In a l') by (apply H; simpl; auto).
destruct (In_split _ _ Ha) as (l1 & l2 & H12).
rewrite H12.
apply Permutation_cons_app.
apply IH; auto.
* apply NoDup_remove_1 with a; rewrite <- H12; auto.
* intro x. split; intros Hx.
+ assert (Hx' : In x l') by (apply H; simpl; auto).
rewrite in_middle in Hx'; eauto.
destruct Hx'; auto. subst; intuition.
+ assert (Hx' : In x l') by (rewrite (in_middle l1 l2 a); eauto).
rewrite <- H in Hx'. destruct Hx'; auto.
subst. destruct (NoDup_remove_2 _ _ _ Hl' Hx).
Qed.
Lemma NoDup_Permutation_bis l l' : NoDup l -> NoDup l' ->
length l = length l' -> incl l l' -> Permutation l l'.
Proof.
intros. apply NoDup_Permutation; auto.
split; auto. apply NoDup_cardinal_incl; auto.
Qed.
Lemma Permutation_NoDup l l' : Permutation l l' -> NoDup l -> NoDup l'.
Proof.
induction 1; auto.
* inversion_clear 1; constructor; eauto using Permutation_in.
* inversion_clear 1 as [|? ? H1 H2]. inversion_clear H2; simpl in *.
constructor. simpl; intuition. constructor; intuition.
Qed.
Global Instance Permutation_NoDup' :
Proper (@Permutation A ==> iff) (@NoDup A) | 10.
Proof.
repeat red; eauto using Permutation_NoDup.
Qed.
End Permutation_properties.
Section Permutation_map.
Variable A B : Type.
Variable f : A -> B.
Lemma Permutation_map l l' :
Permutation l l' -> Permutation (map f l) (map f l').
Proof.
induction 1; simpl; eauto.
Qed.
Global Instance Permutation_map' :
Proper (@Permutation A ==> @Permutation B) (map f) | 10.
Proof.
exact Permutation_map.
Qed.
End Permutation_map.
Section Injection.
Definition injective {A B} (f : A->B) :=
forall x y, f x = f y -> x = y.
Lemma injective_map_NoDup {A B} (f:A->B) (l:list A) :
injective f -> NoDup l -> NoDup (map f l).
Proof.
intros Hf. induction 1 as [|x l Hx Hl IH]; simpl; constructor; trivial.
rewrite in_map_iff. intros (y & Hy & Hy'). apply Hf in Hy. now subst.
Qed.
Lemma injective_bounded_surjective n f :
injective f ->
(forall x, x < n -> f x < n) ->
(forall y, y < n -> exists x, x < n /\ f x = y).
Proof.
intros Hf H.
set (l := seq 0 n).
assert (P : incl (map f l) l).
{ intros x. rewrite in_map_iff. intros (y & <- & Hy').
unfold l in *. rewrite in_seq in *. simpl in *.
destruct Hy' as (_,Hy'). auto with arith. }
assert (P' : incl l (map f l)).
{ unfold l.
apply NoDup_cardinal_incl; auto using injective_map_NoDup, seq_NoDup.
now rewrite map_length. }
intros x Hx.
assert (Hx' : In x l) by (unfold l; rewrite in_seq; auto with arith).
apply P' in Hx'.
rewrite in_map_iff in Hx'. destruct Hx' as (y & Hy & Hy').
exists y; split; auto. unfold l in *; rewrite in_seq in Hy'.
destruct Hy'; auto with arith.
Qed.
Lemma nat_bijection_Permutation n f :
injective f -> (forall x, x < n -> f x < n) ->
let l := seq 0 n in Permutation (map f l) l.
Proof.
intros Hf BD.
apply NoDup_Permutation_bis; auto using injective_map_NoDup, seq_NoDup.
* now rewrite map_length.
* intros x. rewrite in_map_iff. intros (y & <- & Hy').
rewrite in_seq in *. simpl in *.
destruct Hy' as (_,Hy'). auto with arith.
Qed.
End Injection.
Section Permutation_alt.
Variable A:Type.
Implicit Type a : A.
Implicit Type l : list A.
(** Alternative characterization of permutation
via [nth_error] and [nth] *)
Let adapt f n :=
let m := f (S n) in if le_lt_dec m (f 0) then m else pred m.
Let adapt_injective f : injective f -> injective (adapt f).
Proof.
unfold adapt. intros Hf x y EQ.
destruct le_lt_dec as [LE|LT]; destruct le_lt_dec as [LE'|LT'].
- now apply eq_add_S, Hf.
- apply Lt.le_lt_or_eq in LE.
destruct LE as [LT|EQ']; [|now apply Hf in EQ'].
unfold lt in LT. rewrite EQ in LT.
rewrite <- (Lt.S_pred _ _ LT') in LT.
elim (Lt.lt_not_le _ _ LT' LT).
- apply Lt.le_lt_or_eq in LE'.
destruct LE' as [LT'|EQ']; [|now apply Hf in EQ'].
unfold lt in LT'. rewrite <- EQ in LT'.
rewrite <- (Lt.S_pred _ _ LT) in LT'.
elim (Lt.lt_not_le _ _ LT LT').
- apply eq_add_S, Hf.
now rewrite (Lt.S_pred _ _ LT), (Lt.S_pred _ _ LT'), EQ.
Qed.
Let adapt_ok a l1 l2 f : injective f -> length l1 = f 0 ->
forall n, nth_error (l1++a::l2) (f (S n)) = nth_error (l1++l2) (adapt f n).
Proof.
unfold adapt. intros Hf E n.
destruct le_lt_dec as [LE|LT].
- apply Lt.le_lt_or_eq in LE.
destruct LE as [LT|EQ]; [|now apply Hf in EQ].
rewrite <- E in LT.
rewrite 2 nth_error_app1; auto.
- rewrite (Lt.S_pred _ _ LT) at 1.
rewrite <- E, (Lt.S_pred _ _ LT) in LT.
rewrite 2 nth_error_app2; auto with arith.
rewrite <- Minus.minus_Sn_m; auto with arith.
Qed.
Lemma Permutation_nth_error l l' :
Permutation l l' <->
(length l = length l' /\
exists f:nat->nat,
injective f /\ forall n, nth_error l' n = nth_error l (f n)).
Proof.
split.
{ intros P.
split; [now apply Permutation_length|].
induction P.
- exists (fun n => n).
split; try red; auto.
- destruct IHP as (f & Hf & Hf').
exists (fun n => match n with O => O | S n => S (f n) end).
split; try red.
* intros [|y] [|z]; simpl; now auto.
* intros [|n]; simpl; auto.
- exists (fun n => match n with 0 => 1 | 1 => 0 | n => n end).
split; try red.
* intros [|[|z]] [|[|t]]; simpl; now auto.
* intros [|[|n]]; simpl; auto.
- destruct IHP1 as (f & Hf & Hf').
destruct IHP2 as (g & Hg & Hg').
exists (fun n => f (g n)).
split; try red.
* auto.
* intros n. rewrite <- Hf'; auto. }
{ revert l. induction l'.
- intros [|l] (E & _); now auto.
- intros l (E & f & Hf & Hf').
simpl in E.
assert (Ha : nth_error l (f 0) = Some a)
by (symmetry; apply (Hf' 0)).
destruct (nth_error_split l (f 0) Ha) as (l1 & l2 & L12 & L1).
rewrite L12. rewrite <- Permutation_middle. constructor.
apply IHl'; split; [|exists (adapt f); split].
* revert E. rewrite L12, !app_length. simpl.
rewrite <- plus_n_Sm. now injection 1.
* now apply adapt_injective.
* intro n. rewrite <- (adapt_ok a), <- L12; auto.
apply (Hf' (S n)). }
Qed.
Lemma Permutation_nth_error_bis l l' :
Permutation l l' <->
exists f:nat->nat,
injective f /\
(forall n, n < length l -> f n < length l) /\
(forall n, nth_error l' n = nth_error l (f n)).
Proof.
rewrite Permutation_nth_error; split.
- intros (E & f & Hf & Hf').
exists f. do 2 (split; trivial).
intros n Hn.
destruct (Lt.le_or_lt (length l) (f n)) as [LE|LT]; trivial.
rewrite <- nth_error_None, <- Hf', nth_error_None, <- E in LE.
elim (Lt.lt_not_le _ _ Hn LE).
- intros (f & Hf & Hf2 & Hf3); split; [|exists f; auto].
assert (H : length l' <= length l') by auto with arith.
rewrite <- nth_error_None, Hf3, nth_error_None in H.
destruct (Lt.le_or_lt (length l) (length l')) as [LE|LT];
[|apply Hf2 in LT; elim (Lt.lt_not_le _ _ LT H)].
apply Lt.le_lt_or_eq in LE. destruct LE as [LT|EQ]; trivial.
rewrite <- nth_error_Some, Hf3, nth_error_Some in LT.
destruct (injective_bounded_surjective Hf Hf2 LT) as (y & Hy & Hy').
apply Hf in Hy'. subst y. elim (Lt.lt_irrefl _ Hy).
Qed.
Lemma Permutation_nth l l' d :
Permutation l l' <->
(let n := length l in
length l' = n /\
exists f:nat->nat,
(forall x, x < n -> f x < n) /\
(forall x y, x < n -> y < n -> f x = f y -> x = y) /\
(forall x, x < n -> nth x l' d = nth (f x) l d)).
Proof.
split.
- intros H.
assert (E := Permutation_length H).
split; auto.
apply Permutation_nth_error_bis in H.
destruct H as (f & Hf & Hf2 & Hf3).
exists f. split; [|split]; auto.
intros n Hn. rewrite <- 2 nth_default_eq. unfold nth_default.
now rewrite Hf3.
- intros (E & f & Hf1 & Hf2 & Hf3).
rewrite Permutation_nth_error.
split; auto.
exists (fun n => if le_lt_dec (length l) n then n else f n).
split.
* intros x y.
destruct le_lt_dec as [LE|LT];
destruct le_lt_dec as [LE'|LT']; auto.
+ apply Hf1 in LT'. intros ->.
elim (Lt.lt_irrefl (f y)). eapply Lt.lt_le_trans; eauto.
+ apply Hf1 in LT. intros <-.
elim (Lt.lt_irrefl (f x)). eapply Lt.lt_le_trans; eauto.
* intros n.
destruct le_lt_dec as [LE|LT].
+ assert (LE' : length l' <= n) by (now rewrite E).
rewrite <- nth_error_None in LE, LE'. congruence.
+ assert (LT' : n < length l') by (now rewrite E).
specialize (Hf3 n LT). rewrite <- 2 nth_default_eq in Hf3.
unfold nth_default in Hf3.
apply Hf1 in LT.
rewrite <- nth_error_Some in LT, LT'.
do 2 destruct nth_error; congruence.
Qed.
End Permutation_alt.
(* begin hide *)
Notation Permutation_app_swap := Permutation_app_comm (only parsing).
(* end hide *)

View File

@@ -1,2 +0,0 @@
Require Export Sorted.
Require Export Mergesort.

62
samples/Coq/Spec.v Normal file
View File

@@ -0,0 +1,62 @@
(** Specifications. *)
Require Import Coq.Lists.List.
Require Import Coq.Strings.Ascii.
Require Import FunctionNinjas.All.
Require Import ListString.All.
Require Import Computation.
Import ListNotations.
Local Open Scope char.
(** A run is an execution of the program with explicit answers for the
system calls. *)
Module Run.
(** We define a run by induction on the structure of a computation. *)
Inductive t : C.t -> Type :=
| Ret : t C.Ret
| Call : forall (command : Command.t) (answer : Command.answer command)
{handler : Command.answer command -> C.t}, t (handler answer) ->
t (C.Call command handler).
(** The trace of a run. *)
Fixpoint trace {x : C.t} (run : t x)
: list {command : Command.t & Command.answer command} :=
match run with
| Ret => []
| Call command answer _ run => existT _ command answer :: trace run
end.
End Run.
Module Temporal.
Module All.
Inductive t (P : Command.t -> Prop) : C.t -> Prop :=
| Ret : t P C.Ret
| Call : forall (c : Command.t) (h : Command.answer c -> C.t),
P c -> (forall a, t P (h a)) ->
t P (C.Call c h).
End All.
Module One.
Inductive t (P : Command.t -> Prop) : C.t -> Prop :=
| CallThis : forall (c : Command.t) (h : Command.answer c -> C.t),
P c ->
t P (C.Call c h)
| CallOther : forall (c : Command.t) (h : Command.answer c -> C.t),
(forall a, t P (h a)) ->
t P (C.Call c h).
End One.
Module Then.
Inductive t (P1 P2 : Command.t -> Prop) : C.t -> Prop :=
| Ret : t P1 P2 C.Ret
| Call : forall (c : Command.t) (h : Command.answer c -> C.t),
(forall a, t P1 P2 (h a)) ->
t P1 P2 (C.Call c h)
| CallThen : forall (c : Command.t) (h : Command.answer c -> C.t),
P1 c -> (forall a, One.t P2 (h a)) ->
t P1 P2 (C.Call c h).
End Then.
End Temporal.
Module CardBeforeMoney.
End CardBeforeMoney.

View File

@@ -1,419 +0,0 @@
(** Sketch of the proof of {p:nat|p<=n} = {p:nat|p<=m} -> n=m
- preliminary results on the irrelevance of boundedness proofs
- introduce the notion of finite cardinal |A|
- prove that |{p:nat|p<=n}| = n
- prove that |A| = n /\ |A| = m -> n = m if equality is decidable on A
- prove that equality is decidable on A
- conclude
*)
(** * Preliminary results on [nat] and [le] *)
(** Proving axiom K on [nat] *)
Require Import Eqdep_dec.
Require Import Arith.
Theorem eq_rect_eq_nat :
forall (p:nat) (Q:nat->Type) (x:Q p) (h:p=p), x = eq_rect p Q x p h.
Proof.
intros.
apply K_dec_set with (p := h).
apply eq_nat_dec.
reflexivity.
Qed.
(** Proving unicity of proofs of [(n<=m)%nat] *)
Scheme le_ind' := Induction for le Sort Prop.
Theorem le_uniqueness_proof : forall (n m : nat) (p q : n <= m), p = q.
Proof.
induction p using le_ind'; intro q.
replace (le_n n) with
(eq_rect _ (fun n0 => n <= n0) (le_n n) _ (refl_equal n)).
2:reflexivity.
generalize (refl_equal n).
pattern n at 2 4 6 10, q; case q; [intro | intros m l e].
rewrite <- eq_rect_eq_nat; trivial.
contradiction (le_Sn_n m); rewrite <- e; assumption.
replace (le_S n m p) with
(eq_rect _ (fun n0 => n <= n0) (le_S n m p) _ (refl_equal (S m))).
2:reflexivity.
generalize (refl_equal (S m)).
pattern (S m) at 1 3 4 6, q; case q; [intro Heq | intros m0 l HeqS].
contradiction (le_Sn_n m); rewrite Heq; assumption.
injection HeqS; intro Heq; generalize l HeqS.
rewrite <- Heq; intros; rewrite <- eq_rect_eq_nat.
rewrite (IHp l0); reflexivity.
Qed.
(** Proving irrelevance of boundedness proofs while building
elements of interval *)
Lemma dep_pair_intro :
forall (n x y:nat) (Hx : x<=n) (Hy : y<=n), x=y ->
exist (fun x => x <= n) x Hx = exist (fun x => x <= n) y Hy.
Proof.
intros n x y Hx Hy Heq.
generalize Hy.
rewrite <- Heq.
intros.
rewrite (le_uniqueness_proof x n Hx Hy0).
reflexivity.
Qed.
(** * Proving that {p:nat|p<=n} = {p:nat|p<=m} -> n=m *)
(** Definition of having finite cardinality [n+1] for a set [A] *)
Definition card (A:Set) n :=
exists f,
(forall x:A, f x <= n) /\
(forall x y:A, f x = f y -> x = y) /\
(forall m, m <= n -> exists x:A, f x = m).
Require Import Arith.
(** Showing that the interval [0;n] has cardinality [n+1] *)
Theorem card_interval : forall n, card {x:nat|x<=n} n.
Proof.
intro n.
exists (fun x:{x:nat|x<=n} => proj1_sig x).
split.
(* bounded *)
intro x; apply (proj2_sig x).
split.
(* injectivity *)
intros (p,Hp) (q,Hq).
simpl.
intro Hpq.
apply dep_pair_intro; assumption.
(* surjectivity *)
intros m Hmn.
exists (exist (fun x : nat => x <= n) m Hmn).
reflexivity.
Qed.
(** Showing that equality on the interval [0;n] is decidable *)
Lemma interval_dec :
forall n (x y : {m:nat|m<=n}), {x=y}+{x<>y}.
Proof.
intros n (p,Hp).
induction p; intros ([|q],Hq).
left.
apply dep_pair_intro.
reflexivity.
right.
intro H; discriminate H.
right.
intro H; discriminate H.
assert (Hp' : p <= n).
apply le_Sn_le; assumption.
assert (Hq' : q <= n).
apply le_Sn_le; assumption.
destruct (IHp Hp' (exist (fun m => m <= n) q Hq'))
as [Heq|Hneq].
left.
injection Heq; intro Heq'.
apply dep_pair_intro.
apply eq_S.
assumption.
right.
intro HeqS.
injection HeqS; intro Heq.
apply Hneq.
apply dep_pair_intro.
assumption.
Qed.
(** Showing that the cardinality relation is functional on decidable sets *)
Lemma card_inj_aux :
forall (A:Type) f g n,
(forall x:A, f x <= 0) ->
(forall x y:A, f x = f y -> x = y) ->
(forall m, m <= S n -> exists x:A, g x = m)
-> False.
Proof.
intros A f g n Hfbound Hfinj Hgsurj.
destruct (Hgsurj (S n) (le_n _)) as (x,Hx).
destruct (Hgsurj n (le_S _ _ (le_n _))) as (x',Hx').
assert (Hfx : 0 = f x).
apply le_n_O_eq.
apply Hfbound.
assert (Hfx' : 0 = f x').
apply le_n_O_eq.
apply Hfbound.
assert (x=x').
apply Hfinj.
rewrite <- Hfx.
rewrite <- Hfx'.
reflexivity.
rewrite H in Hx.
rewrite Hx' in Hx.
apply (n_Sn _ Hx).
Qed.
(** For [dec_restrict], we use a lemma on the negation of equality
that requires proof-irrelevance. It should be possible to avoid this
lemma by generalizing over a first-order definition of [x<>y], say
[neq] such that [{x=y}+{neq x y}] and [~(x=y /\ neq x y)]; for such
[neq], unicity of proofs could be proven *)
Require Import Classical.
Lemma neq_dep_intro :
forall (A:Set) (z x y:A) (p:x<>z) (q:y<>z), x=y ->
exist (fun x => x <> z) x p = exist (fun x => x <> z) y q.
Proof.
intros A z x y p q Heq.
generalize q; clear q; rewrite <- Heq; intro q.
rewrite (proof_irrelevance _ p q); reflexivity.
Qed.
Lemma dec_restrict :
forall (A:Set),
(forall x y :A, {x=y}+{x<>y}) ->
forall z (x y :{a:A|a<>z}), {x=y}+{x<>y}.
Proof.
intros A Hdec z (x,Hx) (y,Hy).
destruct (Hdec x y) as [Heq|Hneq].
left; apply neq_dep_intro; assumption.
right; intro Heq; injection Heq; exact Hneq.
Qed.
Lemma pred_inj : forall n m,
0 <> n -> 0 <> m -> pred m = pred n -> m = n.
Proof.
destruct n.
intros m H; destruct H; reflexivity.
destruct m.
intros _ H; destruct H; reflexivity.
simpl; intros _ _ H.
rewrite H.
reflexivity.
Qed.
Lemma le_neq_lt : forall n m, n <= m -> n<>m -> n < m.
Proof.
intros n m Hle Hneq.
destruct (le_lt_eq_dec n m Hle).
assumption.
contradiction.
Qed.
Lemma inj_restrict :
forall (A:Set) (f:A->nat) x y z,
(forall x y : A, f x = f y -> x = y)
-> x <> z -> f y < f z -> f z <= f x
-> pred (f x) = f y
-> False.
(* Search error sans le type de f !! *)
Proof.
intros A f x y z Hfinj Hneqx Hfy Hfx Heq.
assert (f z <> f x).
apply sym_not_eq.
intro Heqf.
apply Hneqx.
apply Hfinj.
assumption.
assert (f x = S (f y)).
assert (0 < f x).
apply le_lt_trans with (f z).
apply le_O_n.
apply le_neq_lt; assumption.
apply pred_inj.
apply O_S.
apply lt_O_neq; assumption.
exact Heq.
assert (f z <= f y).
destruct (le_lt_or_eq _ _ Hfx).
apply lt_n_Sm_le.
rewrite <- H0.
assumption.
contradiction Hneqx.
symmetry.
apply Hfinj.
assumption.
contradiction (lt_not_le (f y) (f z)).
Qed.
Theorem card_inj : forall m n (A:Set),
(forall x y :A, {x=y}+{x<>y}) ->
card A m -> card A n -> m = n.
Proof.
induction m; destruct n;
intros A Hdec
(f,(Hfbound,(Hfinj,Hfsurj)))
(g,(Hgbound,(Hginj,Hgsurj))).
(* 0/0 *)
reflexivity.
(* 0/Sm *)
destruct (card_inj_aux _ _ _ _ Hfbound Hfinj Hgsurj).
(* Sn/0 *)
destruct (card_inj_aux _ _ _ _ Hgbound Hginj Hfsurj).
(* Sn/Sm *)
destruct (Hgsurj (S n) (le_n _)) as (xSn,HSnx).
rewrite IHm with (n:=n) (A := {x:A|x<>xSn}).
reflexivity.
(* decidability of eq on {x:A|x<>xSm} *)
apply dec_restrict.
assumption.
(* cardinality of {x:A|x<>xSn} is m *)
pose (f' := fun x' : {x:A|x<>xSn} =>
let (x,Hneq) := x' in
if le_lt_dec (f xSn) (f x)
then pred (f x)
else f x).
exists f'.
split.
(* f' is bounded *)
unfold f'.
intros (x,_).
destruct (le_lt_dec (f xSn) (f x)) as [Hle|Hge].
change m with (pred (S m)).
apply le_pred.
apply Hfbound.
apply le_S_n.
apply le_trans with (f xSn).
exact Hge.
apply Hfbound.
split.
(* f' is injective *)
unfold f'.
intros (x,Hneqx) (y,Hneqy) Heqf'.
destruct (le_lt_dec (f xSn) (f x)) as [Hlefx|Hgefx];
destruct (le_lt_dec (f xSn) (f y)) as [Hlefy|Hgefy].
(* f xSn <= f x et f xSn <= f y *)
assert (Heq : x = y).
apply Hfinj.
assert (f xSn <> f y).
apply sym_not_eq.
intro Heqf.
apply Hneqy.
apply Hfinj.
assumption.
assert (0 < f y).
apply le_lt_trans with (f xSn).
apply le_O_n.
apply le_neq_lt; assumption.
assert (f xSn <> f x).
apply sym_not_eq.
intro Heqf.
apply Hneqx.
apply Hfinj.
assumption.
assert (0 < f x).
apply le_lt_trans with (f xSn).
apply le_O_n.
apply le_neq_lt; assumption.
apply pred_inj.
apply lt_O_neq; assumption.
apply lt_O_neq; assumption.
assumption.
apply neq_dep_intro; assumption.
(* f y < f xSn <= f x *)
destruct (inj_restrict A f x y xSn); assumption.
(* f x < f xSn <= f y *)
symmetry in Heqf'.
destruct (inj_restrict A f y x xSn); assumption.
(* f x < f xSn et f y < f xSn *)
assert (Heq : x=y).
apply Hfinj; assumption.
apply neq_dep_intro; assumption.
(* f' is surjective *)
intros p Hlep.
destruct (le_lt_dec (f xSn) p) as [Hle|Hlt].
(* case f xSn <= p *)
destruct (Hfsurj (S p) (le_n_S _ _ Hlep)) as (x,Hx).
assert (Hneq : x <> xSn).
intro Heqx.
rewrite Heqx in Hx.
rewrite Hx in Hle.
apply le_Sn_n with p; assumption.
exists (exist (fun a => a<>xSn) x Hneq).
unfold f'.
destruct (le_lt_dec (f xSn) (f x)) as [Hle'|Hlt'].
rewrite Hx; reflexivity.
rewrite Hx in Hlt'.
contradiction (le_not_lt (f xSn) p).
apply lt_trans with (S p).
apply lt_n_Sn.
assumption.
(* case p < f xSn *)
destruct (Hfsurj p (le_S _ _ Hlep)) as (x,Hx).
assert (Hneq : x <> xSn).
intro Heqx.
rewrite Heqx in Hx.
rewrite Hx in Hlt.
apply (lt_irrefl p).
assumption.
exists (exist (fun a => a<>xSn) x Hneq).
unfold f'.
destruct (le_lt_dec (f xSn) (f x)) as [Hle'|Hlt'].
rewrite Hx in Hle'.
contradiction (lt_irrefl p).
apply lt_le_trans with (f xSn); assumption.
assumption.
(* cardinality of {x:A|x<>xSn} is n *)
pose (g' := fun x' : {x:A|x<>xSn} =>
let (x,Hneq) := x' in
if Hdec x xSn then 0 else g x).
exists g'.
split.
(* g is bounded *)
unfold g'.
intros (x,_).
destruct (Hdec x xSn) as [_|Hneq].
apply le_O_n.
assert (Hle_gx:=Hgbound x).
destruct (le_lt_or_eq _ _ Hle_gx).
apply lt_n_Sm_le.
assumption.
contradiction Hneq.
apply Hginj.
rewrite HSnx.
assumption.
split.
(* g is injective *)
unfold g'.
intros (x,Hneqx) (y,Hneqy) Heqg'.
destruct (Hdec x xSn) as [Heqx|_].
contradiction Hneqx.
destruct (Hdec y xSn) as [Heqy|_].
contradiction Hneqy.
assert (Heq : x=y).
apply Hginj; assumption.
apply neq_dep_intro; assumption.
(* g is surjective *)
intros p Hlep.
destruct (Hgsurj p (le_S _ _ Hlep)) as (x,Hx).
assert (Hneq : x<>xSn).
intro Heq.
rewrite Heq in Hx.
rewrite Hx in HSnx.
rewrite HSnx in Hlep.
contradiction (le_Sn_n _ Hlep).
exists (exist (fun a => a<>xSn) x Hneq).
simpl.
destruct (Hdec x xSn) as [Heqx|_].
contradiction Hneq.
assumption.
Qed.
(** Conclusion *)
Theorem interval_discr :
forall n m, {p:nat|p<=n} = {p:nat|p<=m} -> n=m.
Proof.
intros n m Heq.
apply card_inj with (A := {p:nat|p<=n}).
apply interval_dec.
apply card_interval.
rewrite Heq.
apply card_interval.
Qed.

24
samples/EBNF/grammar.ebnf Normal file
View File

@@ -0,0 +1,24 @@
(*
Source: https://github.com/sunjay/lion
License: MIT
*)
Statement = ( NamedFunction | AnonymousFunction | Assignment | Expr ) , "\n" ;
Expr = AnonymousFunction | Term | "(" , Expr , ")" ,
{ AnonymousFunction | Term | "(" , Expr , ")" } ;
Assignment = Symbol , "=" , Expr ;
AnonymousFunction = "\" , FunctionRHS ;
NamedFunction = Symbol , FunctionRHS ;
FunctionRHS = FunctionParams , "=" , FunctionBody ;
FunctionParams = FunctionParam , { FunctionParam } ;
FunctionParam = Term ;
FunctionBody = Expr ;
Term = Symbol | Number | SingleWordString ;
SingleWordString = '"' , Symbol , '"' ;
(* Symbol is a collection of valid symbol characters, not defined here *)
(* Number is a valid numeric literal *)

View File

@@ -0,0 +1,40 @@
(*
Source: https://github.com/io7m/jsom0
License: ISC
*)
name =
"name" , string , ";" ;
diffuse =
"diffuse" , real , real , real , ";" ;
ambient =
"ambient" , real , real , real , ";" ;
specular =
"specular" , real , real , real , real , ";" ;
shininess =
"shininess" , real , ";" ;
alpha =
"alpha" , real , ";" ;
mapping =
"map_chrome" | "map_uv" ;
texture =
"texture" , string , real , mapping , ";" ;
material =
"material" , ";" ,
name ,
diffuse ,
ambient ,
specular ,
shininess ,
alpha ,
[ texture ] ,
"end" , ";" ;

61
samples/EBNF/object.ebnf Normal file
View File

@@ -0,0 +1,61 @@
(*
Source: https://github.com/io7m/jsom0
License: ISC
*)
vertex_p3n3_name =
"vertex_p3n3" ;
vertex_p3n3t2_name =
"vertex_p3n3t2" ;
vertex_type =
vertex_p3n3_name | vertex_p3n3t2_name ;
vertex_position =
"position" , real , real , real , ";" ;
vertex_normal =
"normal" , real , real , real , ";" ;
vertex_uv =
"uv" , real , real , ";" ;
vertex_p3n3 =
vertex_p3n3_name , vertex_position , vertex_normal , "end" , ";" ;
vertex_p3n3t2 =
vertex_p3n3t2_name , vertex_position , vertex_normal , vertex_uv , "end" , ";" ;
vertex =
vertex_p3n3 | vertex_p3n3t2 ;
vertex_array =
"array" , positive , vertex_type , { vertex } , "end" , ";" ;
vertices =
"vertices" , ";" , vertex_array , "end" , ";" ;
triangle =
"triangle" , natural , natural , natural , ";" ;
triangle_array =
"array" , positive, "triangle" , { triangle } , "end" , ";" ;
triangles =
"triangles" , ";" , triangle_array , "end" , ";" ;
name =
"name" , string , ";" ;
material_name =
"material_name" , string , ";" ;
object =
"object" , ";" ,
name ,
material_name ,
vertices ,
triangles ,
"end" , ";" ;

20
samples/EBNF/types.ebnf Normal file
View File

@@ -0,0 +1,20 @@
(*
Source: https://github.com/io7m/jsom0
License: ISC
*)
digit_without_zero =
"1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
digit =
"0" | digit_without_zero ;
positive =
digit_without_zero , { digit } ;
natural =
"0" | positive ;
real =
[ "-" ] , digit , [ "." , { digit } ] ;

View File

@@ -0,0 +1,9 @@
(package "composer" "0.0.7" "Interface to PHP Composer")
(source "melpa" "https://melpa.org/packages/")
(package-file "composer.el")
(depends-on "f")
(depends-on "s")
(depends-on "request")
(depends-on "seq")

View File

@@ -0,0 +1,7 @@
{"src/*", [
report,
verbose,
{i, "include"},
{outdir, "ebin"},
debug_info
]}.

59
samples/GN/BUILD.2.gn Normal file
View File

@@ -0,0 +1,59 @@
# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("../gni/isolate.gni")
group("gn_all") {
testonly = true
if (v8_test_isolation_mode != "noop") {
deps = [
":check-static-initializers_run",
":jsfunfuzz_run",
":run-deopt-fuzzer_run",
":run-gcmole_run",
":run-valgrind_run",
]
}
}
v8_isolate_run("check-static-initializers") {
deps = [
"..:d8_run",
]
isolate = "check-static-initializers.isolate"
}
v8_isolate_run("jsfunfuzz") {
deps = [
"..:d8_run",
]
isolate = "jsfunfuzz/jsfunfuzz.isolate"
}
v8_isolate_run("run-deopt-fuzzer") {
deps = [
"..:d8_run",
]
isolate = "run-deopt-fuzzer.isolate"
}
v8_isolate_run("run-gcmole") {
deps = [
"..:d8_run",
]
isolate = "gcmole/run-gcmole.isolate"
}
v8_isolate_run("run-valgrind") {
deps = [
"..:d8_run",
]
isolate = "run-valgrind.isolate"
}

1646
samples/GN/BUILD.3.gn Normal file

File diff suppressed because it is too large Load Diff

2583
samples/GN/BUILD.gn Normal file

File diff suppressed because it is too large Load Diff

2781
samples/GN/android-rules.gni Normal file

File diff suppressed because it is too large Load Diff

13
samples/GN/clang.gni Normal file
View File

@@ -0,0 +1,13 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/toolchain/toolchain.gni")
declare_args() {
# Indicates if the build should use the Chrome-specific plugins for enforcing
# coding guidelines, etc. Only used when compiling with Clang.
clang_use_chrome_plugins = is_clang && !is_nacl && !use_xcode_clang
clang_base_path = "//third_party/llvm-build/Release+Asserts"
}

25
samples/GN/filenames/.gn Normal file
View File

@@ -0,0 +1,25 @@
# This file is used by the GN meta build system to find the root of the source
# tree and to set startup options. For documentation on the values set in this
# file, run "gn help dotfile" at the command line.
import("//build/dotfile_settings.gni")
# The location of the build configuration file.
buildconfig = "//build/config/BUILDCONFIG.gn"
# The secondary source root is a parallel directory tree where
# GN build files are placed when they can not be placed directly
# in the source tree, e.g. for third party source trees.
secondary_source = "//build/secondary/"
# These are the targets to check headers for by default. The files in targets
# matching these patterns (see "gn help label_pattern" for format) will have
# their includes checked for proper dependencies when you run either
# "gn check" or "gn gen --check".
check_targets = []
# These are the list of GN files that run exec_script. This whitelist exists
# to force additional review for new uses of exec_script, which is strongly
# discouraged except for gypi_to_gn calls.
exec_script_whitelist =
build_dotfile_settings.exec_script_whitelist + [ "//test/test262/BUILD.gn" ]

View File

@@ -0,0 +1,503 @@
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/config.gni")
import("//build/config/clang/clang.gni")
import("//build/config/nacl/config.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/config/v8_target_cpu.gni")
import("//build/toolchain/cc_wrapper.gni")
import("//build/toolchain/goma.gni")
import("//build/toolchain/toolchain.gni")
# This template defines a toolchain for something that works like gcc
# (including clang).
#
# It requires the following variables specifying the executables to run:
# - ar
# - cc
# - cxx
# - ld
#
# Optional parameters that control the tools:
#
# - extra_cflags
# Extra flags to be appended when compiling C files (but not C++ files).
# - extra_cppflags
# Extra flags to be appended when compiling both C and C++ files. "CPP"
# stands for "C PreProcessor" in this context, although it can be
# used for non-preprocessor flags as well. Not to be confused with
# "CXX" (which follows).
# - extra_cxxflags
# Extra flags to be appended when compiling C++ files (but not C files).
# - extra_ldflags
# Extra flags to be appended when linking
#
# - libs_section_prefix
# - libs_section_postfix
# The contents of these strings, if specified, will be placed around
# the libs section of the linker line. It allows one to inject libraries
# at the beginning and end for all targets in a toolchain.
# - solink_libs_section_prefix
# - solink_libs_section_postfix
# Same as libs_section_{pre,post}fix except used for solink instead of link.
# - link_outputs
# The content of this array, if specified, will be added to the list of
# outputs from the link command. This can be useful in conjunction with
# the post_link parameter.
# - post_link
# The content of this string, if specified, will be run as a separate
# command following the the link command.
# - deps
# Just forwarded to the toolchain definition.
# - executable_extension
# If this string is specified it will be used for the file extension
# for an executable, rather than using no extension; targets will
# still be able to override the extension using the output_extension
# variable.
# - rebuild_define
# The contents of this string, if specified, will be passed as a #define
# to the toolchain. It can be used to force recompiles whenever a
# toolchain is updated.
# - shlib_extension
# If this string is specified it will be used for the file extension
# for a shared library, rather than default value specified in
# toolchain.gni
# - strip
# Location of the strip executable. When specified, strip will be run on
# all shared libraries and executables as they are built. The pre-stripped
# artifacts will be put in lib.unstripped/ and exe.unstripped/.
template("gcc_toolchain") {
toolchain(target_name) {
assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value")
assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value")
assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value")
assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value")
# This define changes when the toolchain changes, forcing a rebuild.
# Nothing should ever use this define.
if (defined(invoker.rebuild_define)) {
rebuild_string = "-D" + invoker.rebuild_define + " "
} else {
rebuild_string = ""
}
# GN's syntax can't handle more than one scope dereference at once, like
# "invoker.toolchain_args.foo", so make a temporary to hold the toolchain
# args so we can do "invoker_toolchain_args.foo".
assert(defined(invoker.toolchain_args),
"Toolchains must specify toolchain_args")
invoker_toolchain_args = invoker.toolchain_args
assert(defined(invoker_toolchain_args.current_cpu),
"toolchain_args must specify a current_cpu")
assert(defined(invoker_toolchain_args.current_os),
"toolchain_args must specify a current_os")
# When invoking this toolchain not as the default one, these args will be
# passed to the build. They are ignored when this is the default toolchain.
toolchain_args = {
# Populate toolchain args from the invoker.
forward_variables_from(invoker_toolchain_args, "*")
# The host toolchain value computed by the default toolchain's setup
# needs to be passed through unchanged to all secondary toolchains to
# ensure that it's always the same, regardless of the values that may be
# set on those toolchains.
host_toolchain = host_toolchain
if (!defined(invoker_toolchain_args.v8_current_cpu)) {
v8_current_cpu = invoker_toolchain_args.current_cpu
}
}
# When the invoker has explicitly overridden use_goma or cc_wrapper in the
# toolchain args, use those values, otherwise default to the global one.
# This works because the only reasonable override that toolchains might
# supply for these values are to force-disable them.
if (defined(toolchain_args.use_goma)) {
toolchain_uses_goma = toolchain_args.use_goma
} else {
toolchain_uses_goma = use_goma
}
if (defined(toolchain_args.cc_wrapper)) {
toolchain_cc_wrapper = toolchain_args.cc_wrapper
} else {
toolchain_cc_wrapper = cc_wrapper
}
# Compute the compiler prefix.
if (toolchain_uses_goma) {
assert(toolchain_cc_wrapper == "",
"Goma and cc_wrapper can't be used together.")
compiler_prefix = "$goma_dir/gomacc "
} else if (toolchain_cc_wrapper != "") {
compiler_prefix = toolchain_cc_wrapper + " "
} else {
compiler_prefix = ""
}
cc = compiler_prefix + invoker.cc
cxx = compiler_prefix + invoker.cxx
ar = invoker.ar
ld = invoker.ld
if (defined(invoker.readelf)) {
readelf = invoker.readelf
} else {
readelf = "readelf"
}
if (defined(invoker.nm)) {
nm = invoker.nm
} else {
nm = "nm"
}
if (defined(invoker.shlib_extension)) {
default_shlib_extension = invoker.shlib_extension
} else {
default_shlib_extension = shlib_extension
}
if (defined(invoker.executable_extension)) {
default_executable_extension = invoker.executable_extension
} else {
default_executable_extension = ""
}
# Bring these into our scope for string interpolation with default values.
if (defined(invoker.libs_section_prefix)) {
libs_section_prefix = invoker.libs_section_prefix
} else {
libs_section_prefix = ""
}
if (defined(invoker.libs_section_postfix)) {
libs_section_postfix = invoker.libs_section_postfix
} else {
libs_section_postfix = ""
}
if (defined(invoker.solink_libs_section_prefix)) {
solink_libs_section_prefix = invoker.solink_libs_section_prefix
} else {
solink_libs_section_prefix = ""
}
if (defined(invoker.solink_libs_section_postfix)) {
solink_libs_section_postfix = invoker.solink_libs_section_postfix
} else {
solink_libs_section_postfix = ""
}
if (defined(invoker.extra_cflags) && invoker.extra_cflags != "") {
extra_cflags = " " + invoker.extra_cflags
} else {
extra_cflags = ""
}
if (defined(invoker.extra_cppflags) && invoker.extra_cppflags != "") {
extra_cppflags = " " + invoker.extra_cppflags
} else {
extra_cppflags = ""
}
if (defined(invoker.extra_cxxflags) && invoker.extra_cxxflags != "") {
extra_cxxflags = " " + invoker.extra_cxxflags
} else {
extra_cxxflags = ""
}
if (defined(invoker.extra_ldflags) && invoker.extra_ldflags != "") {
extra_ldflags = " " + invoker.extra_ldflags
} else {
extra_ldflags = ""
}
# These library switches can apply to all tools below.
lib_switch = "-l"
lib_dir_switch = "-L"
# Object files go in this directory.
object_subdir = "{{target_out_dir}}/{{label_name}}"
tool("cc") {
depfile = "{{output}}.d"
command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}${extra_cppflags}${extra_cflags} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CC {{output}}"
outputs = [
# The whitelist file is also an output, but ninja does not
# currently support multiple outputs for tool("cc").
"$object_subdir/{{source_name_part}}.o",
]
if (enable_resource_whitelist_generation) {
compile_wrapper =
rebase_path("//build/toolchain/gcc_compile_wrapper.py",
root_build_dir)
command = "$python_path \"$compile_wrapper\" --resource-whitelist=\"{{output}}.whitelist\" $command"
}
}
tool("cxx") {
depfile = "{{output}}.d"
command = "$cxx -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CXX {{output}}"
outputs = [
# The whitelist file is also an output, but ninja does not
# currently support multiple outputs for tool("cxx").
"$object_subdir/{{source_name_part}}.o",
]
if (enable_resource_whitelist_generation) {
compile_wrapper =
rebase_path("//build/toolchain/gcc_compile_wrapper.py",
root_build_dir)
command = "$python_path \"$compile_wrapper\" --resource-whitelist=\"{{output}}.whitelist\" $command"
}
}
tool("asm") {
# For GCC we can just use the C compiler to compile assembly.
depfile = "{{output}}.d"
command = "$cc -MMD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "ASM {{output}}"
outputs = [
"$object_subdir/{{source_name_part}}.o",
]
}
tool("alink") {
rspfile = "{{output}}.rsp"
whitelist_flag = " "
if (enable_resource_whitelist_generation) {
whitelist_flag = " --resource-whitelist=\"{{output}}.whitelist\""
}
# This needs a Python script to avoid using simple sh features in this
# command, in case the host does not use a POSIX shell (e.g. compiling
# POSIX-like toolchains such as NaCl on Windows).
ar_wrapper =
rebase_path("//build/toolchain/gcc_ar_wrapper.py", root_build_dir)
command = "$python_path \"$ar_wrapper\"$whitelist_flag --output={{output}} --ar=\"$ar\" {{arflags}} rcsD @\"$rspfile\""
description = "AR {{output}}"
rspfile_content = "{{inputs}}"
outputs = [
"{{output_dir}}/{{target_output_name}}{{output_extension}}",
]
# Shared libraries go in the target out directory by default so we can
# generate different targets with the same name and not have them collide.
default_output_dir = "{{target_out_dir}}"
default_output_extension = ".a"
output_prefix = "lib"
}
tool("solink") {
soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
sofile = "{{output_dir}}/$soname" # Possibly including toolchain dir.
rspfile = sofile + ".rsp"
pool = "//build/toolchain:link_pool($default_toolchain)"
whitelist_flag = " "
if (enable_resource_whitelist_generation) {
whitelist_file = "$sofile.whitelist"
whitelist_flag = " --resource-whitelist=\"$whitelist_file\""
}
if (defined(invoker.strip)) {
unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname"
} else {
unstripped_sofile = sofile
}
# These variables are not built into GN but are helpers that
# implement (1) linking to produce a .so, (2) extracting the symbols
# from that file (3) if the extracted list differs from the existing
# .TOC file, overwrite it, otherwise, don't change it.
tocfile = sofile + ".TOC"
link_command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" -Wl,-soname=\"$soname\" @\"$rspfile\""
assert(defined(readelf), "to solink you must have a readelf")
assert(defined(nm), "to solink you must have an nm")
strip_switch = ""
if (defined(invoker.strip)) {
strip_switch = "--strip=${invoker.strip}"
}
# This needs a Python script to avoid using a complex shell command
# requiring sh control structures, pipelines, and POSIX utilities.
# The host might not have a POSIX shell and utilities (e.g. Windows).
solink_wrapper = rebase_path("//build/toolchain/gcc_solink_wrapper.py")
command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch --sofile=\"$unstripped_sofile\" --tocfile=\"$tocfile\" --output=\"$sofile\"$whitelist_flag -- $link_command"
rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix"
description = "SOLINK $sofile"
# Use this for {{output_extension}} expansions unless a target manually
# overrides it (in which case {{output_extension}} will be what the target
# specifies).
default_output_extension = default_shlib_extension
default_output_dir = "{{root_out_dir}}"
if (shlib_subdir != ".") {
default_output_dir += "/$shlib_subdir"
}
output_prefix = "lib"
# Since the above commands only updates the .TOC file when it changes, ask
# Ninja to check if the timestamp actually changed to know if downstream
# dependencies should be recompiled.
restat = true
# Tell GN about the output files. It will link to the sofile but use the
# tocfile for dependency management.
outputs = [
sofile,
tocfile,
]
if (enable_resource_whitelist_generation) {
outputs += [ whitelist_file ]
}
if (sofile != unstripped_sofile) {
outputs += [ unstripped_sofile ]
}
link_output = sofile
depend_output = tocfile
}
tool("solink_module") {
soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
sofile = "{{output_dir}}/$soname"
rspfile = sofile + ".rsp"
pool = "//build/toolchain:link_pool($default_toolchain)"
if (defined(invoker.strip)) {
unstripped_sofile = "{{root_out_dir}}/lib.unstripped/$soname"
} else {
unstripped_sofile = sofile
}
command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" -Wl,-soname=\"$soname\" @\"$rspfile\""
if (defined(invoker.strip)) {
strip_command = "${invoker.strip} --strip-unneeded -o \"$sofile\" \"$unstripped_sofile\""
command += " && " + strip_command
}
rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix"
description = "SOLINK_MODULE $sofile"
# Use this for {{output_extension}} expansions unless a target manually
# overrides it (in which case {{output_extension}} will be what the target
# specifies).
if (defined(invoker.loadable_module_extension)) {
default_output_extension = invoker.loadable_module_extension
} else {
default_output_extension = default_shlib_extension
}
default_output_dir = "{{root_out_dir}}"
if (shlib_subdir != ".") {
default_output_dir += "/$shlib_subdir"
}
output_prefix = "lib"
outputs = [
sofile,
]
if (sofile != unstripped_sofile) {
outputs += [ unstripped_sofile ]
}
}
tool("link") {
exename = "{{target_output_name}}{{output_extension}}"
outfile = "{{output_dir}}/$exename"
rspfile = "$outfile.rsp"
unstripped_outfile = outfile
pool = "//build/toolchain:link_pool($default_toolchain)"
# Use this for {{output_extension}} expansions unless a target manually
# overrides it (in which case {{output_extension}} will be what the target
# specifies).
default_output_extension = default_executable_extension
default_output_dir = "{{root_out_dir}}"
if (defined(invoker.strip)) {
unstripped_outfile = "{{root_out_dir}}/exe.unstripped/$exename"
}
command = "$ld {{ldflags}}${extra_ldflags} -o \"$unstripped_outfile\" -Wl,--start-group @\"$rspfile\" {{solibs}} -Wl,--end-group $libs_section_prefix {{libs}} $libs_section_postfix"
if (defined(invoker.strip)) {
link_wrapper =
rebase_path("//build/toolchain/gcc_link_wrapper.py", root_build_dir)
command = "$python_path \"$link_wrapper\" --strip=\"${invoker.strip}\" --unstripped-file=\"$unstripped_outfile\" --output=\"$outfile\" -- $command"
}
description = "LINK $outfile"
rspfile_content = "{{inputs}}"
outputs = [
outfile,
]
if (outfile != unstripped_outfile) {
outputs += [ unstripped_outfile ]
}
if (defined(invoker.link_outputs)) {
outputs += invoker.link_outputs
}
}
# These two are really entirely generic, but have to be repeated in
# each toolchain because GN doesn't allow a template to be used here.
# See //build/toolchain/toolchain.gni for details.
tool("stamp") {
command = stamp_command
description = stamp_description
}
tool("copy") {
command = copy_command
description = copy_description
}
forward_variables_from(invoker, [ "deps" ])
}
}
# This is a shorthand for gcc_toolchain instances based on the Chromium-built
# version of Clang. Only the toolchain_cpu and toolchain_os variables need to
# be specified by the invoker, and optionally toolprefix if it's a
# cross-compile case. Note that for a cross-compile case this toolchain
# requires a config to pass the appropriate -target option, or else it will
# actually just be doing a native compile. The invoker can optionally override
# use_gold too.
template("clang_toolchain") {
if (defined(invoker.toolprefix)) {
toolprefix = invoker.toolprefix
} else {
toolprefix = ""
}
gcc_toolchain(target_name) {
prefix = rebase_path("$clang_base_path/bin", root_build_dir)
cc = "$prefix/clang"
cxx = "$prefix/clang++"
ld = cxx
readelf = "${toolprefix}readelf"
ar = "${toolprefix}ar"
nm = "${toolprefix}nm"
forward_variables_from(invoker, [ "strip" ])
toolchain_args = {
if (defined(invoker.toolchain_args)) {
forward_variables_from(invoker.toolchain_args, "*")
}
is_clang = true
}
}
}

235
samples/GN/icu.gn Normal file
View File

@@ -0,0 +1,235 @@
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/linux/pkg_config.gni")
import("//build/shim_headers.gni")
group("icu") {
public_deps = [
":icui18n",
":icuuc",
]
}
config("icu_config") {
defines = [
"USING_SYSTEM_ICU=1",
"ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC",
]
}
pkg_config("system_icui18n") {
packages = [ "icu-i18n" ]
}
pkg_config("system_icuuc") {
packages = [ "icu-uc" ]
}
source_set("icui18n") {
deps = [
":icui18n_shim",
]
public_configs = [
":icu_config",
":system_icui18n",
]
}
source_set("icuuc") {
deps = [
":icuuc_shim",
]
public_configs = [
":icu_config",
":system_icuuc",
]
}
shim_headers("icui18n_shim") {
root_path = "source/i18n"
headers = [
# This list can easily be updated using the command below:
# find third_party/icu/source/i18n/unicode \
# -iname '*.h' -printf '"%p",\n' | \
# sed -e 's|third_party/icu/i18n/common/||' | sort -u
"unicode/alphaindex.h",
"unicode/basictz.h",
"unicode/calendar.h",
"unicode/choicfmt.h",
"unicode/coleitr.h",
"unicode/coll.h",
"unicode/compactdecimalformat.h",
"unicode/curramt.h",
"unicode/currpinf.h",
"unicode/currunit.h",
"unicode/datefmt.h",
"unicode/dcfmtsym.h",
"unicode/decimfmt.h",
"unicode/dtfmtsym.h",
"unicode/dtitvfmt.h",
"unicode/dtitvinf.h",
"unicode/dtptngen.h",
"unicode/dtrule.h",
"unicode/fieldpos.h",
"unicode/fmtable.h",
"unicode/format.h",
"unicode/fpositer.h",
"unicode/gender.h",
"unicode/gregocal.h",
"unicode/locdspnm.h",
"unicode/measfmt.h",
"unicode/measunit.h",
"unicode/measure.h",
"unicode/msgfmt.h",
"unicode/numfmt.h",
"unicode/numsys.h",
"unicode/plurfmt.h",
"unicode/plurrule.h",
"unicode/rbnf.h",
"unicode/rbtz.h",
"unicode/regex.h",
"unicode/region.h",
"unicode/reldatefmt.h",
"unicode/scientificnumberformatter.h",
"unicode/search.h",
"unicode/selfmt.h",
"unicode/simpletz.h",
"unicode/smpdtfmt.h",
"unicode/sortkey.h",
"unicode/stsearch.h",
"unicode/tblcoll.h",
"unicode/timezone.h",
"unicode/tmunit.h",
"unicode/tmutamt.h",
"unicode/tmutfmt.h",
"unicode/translit.h",
"unicode/tzfmt.h",
"unicode/tznames.h",
"unicode/tzrule.h",
"unicode/tztrans.h",
"unicode/ucal.h",
"unicode/ucol.h",
"unicode/ucoleitr.h",
"unicode/ucsdet.h",
"unicode/ucurr.h",
"unicode/udat.h",
"unicode/udateintervalformat.h",
"unicode/udatpg.h",
"unicode/udisplaycontext.h",
"unicode/ufieldpositer.h",
"unicode/uformattable.h",
"unicode/ugender.h",
"unicode/uldnames.h",
"unicode/ulocdata.h",
"unicode/umsg.h",
"unicode/unirepl.h",
"unicode/unum.h",
"unicode/unumsys.h",
"unicode/upluralrules.h",
"unicode/uregex.h",
"unicode/uregion.h",
"unicode/usearch.h",
"unicode/uspoof.h",
"unicode/utmscale.h",
"unicode/utrans.h",
"unicode/vtzone.h",
]
}
shim_headers("icuuc_shim") {
root_path = "source/common"
headers = [
# This list can easily be updated using the command below:
# find third_party/icu/source/common/unicode \
# -iname '*.h' -printf '"%p",\n' | \
# sed -e 's|third_party/icu/source/common/||' | sort -u
"unicode/appendable.h",
"unicode/brkiter.h",
"unicode/bytestream.h",
"unicode/bytestrie.h",
"unicode/bytestriebuilder.h",
"unicode/caniter.h",
"unicode/chariter.h",
"unicode/dbbi.h",
"unicode/docmain.h",
"unicode/dtintrv.h",
"unicode/enumset.h",
"unicode/errorcode.h",
"unicode/filteredbrk.h",
"unicode/icudataver.h",
"unicode/icuplug.h",
"unicode/idna.h",
"unicode/listformatter.h",
"unicode/localpointer.h",
"unicode/locid.h",
"unicode/messagepattern.h",
"unicode/normalizer2.h",
"unicode/normlzr.h",
"unicode/parseerr.h",
"unicode/parsepos.h",
"unicode/platform.h",
"unicode/ptypes.h",
"unicode/putil.h",
"unicode/rbbi.h",
"unicode/rep.h",
"unicode/resbund.h",
"unicode/schriter.h",
"unicode/std_string.h",
"unicode/strenum.h",
"unicode/stringpiece.h",
"unicode/stringtriebuilder.h",
"unicode/symtable.h",
"unicode/ubidi.h",
"unicode/ubrk.h",
"unicode/ucasemap.h",
"unicode/ucat.h",
"unicode/uchar.h",
"unicode/ucharstrie.h",
"unicode/ucharstriebuilder.h",
"unicode/uchriter.h",
"unicode/uclean.h",
"unicode/ucnv.h",
"unicode/ucnv_cb.h",
"unicode/ucnv_err.h",
"unicode/ucnvsel.h",
"unicode/uconfig.h",
"unicode/udata.h",
"unicode/uenum.h",
"unicode/uidna.h",
"unicode/uiter.h",
"unicode/ulistformatter.h",
"unicode/uloc.h",
"unicode/umachine.h",
"unicode/umisc.h",
"unicode/unifilt.h",
"unicode/unifunct.h",
"unicode/unimatch.h",
"unicode/uniset.h",
"unicode/unistr.h",
"unicode/unorm.h",
"unicode/unorm2.h",
"unicode/uobject.h",
"unicode/urename.h",
"unicode/urep.h",
"unicode/ures.h",
"unicode/uscript.h",
"unicode/uset.h",
"unicode/usetiter.h",
"unicode/ushape.h",
"unicode/usprep.h",
"unicode/ustring.h",
"unicode/ustringtrie.h",
"unicode/utext.h",
"unicode/utf.h",
"unicode/utf16.h",
"unicode/utf32.h",
"unicode/utf8.h",
"unicode/utf_old.h",
"unicode/utrace.h",
"unicode/utypes.h",
"unicode/uvernum.h",
"unicode/uversion.h",
]
}

File diff suppressed because it is too large Load Diff

1422
samples/GN/ios-rules.gni Normal file

File diff suppressed because it is too large Load Diff

193
samples/GN/isolate.gni Normal file
View File

@@ -0,0 +1,193 @@
# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/sanitizers/sanitizers.gni")
import("//third_party/icu/config.gni")
import("v8.gni")
declare_args() {
# Sets the test isolation mode (noop|prepare|check).
v8_test_isolation_mode = "noop"
}
template("v8_isolate_run") {
forward_variables_from(invoker,
"*",
[
"deps",
"isolate",
])
# Remember target name as within the action scope the target name will be
# different.
name = target_name
assert(defined(invoker.deps))
assert(defined(invoker.isolate))
if (name != "" && v8_test_isolation_mode != "noop") {
action(name + "_run") {
testonly = true
deps = invoker.deps
script = "//tools/isolate_driver.py"
sources = [
invoker.isolate,
]
inputs = [
# Files that are known to be involved in this step.
"//tools/swarming_client/isolate.py",
"//tools/swarming_client/run_isolated.py",
]
if (v8_test_isolation_mode == "prepare") {
outputs = [
"$root_out_dir/$name.isolated.gen.json",
]
} else if (v8_test_isolation_mode == "check") {
outputs = [
"$root_out_dir/$name.isolated",
"$root_out_dir/$name.isolated.state",
]
}
# Translate gn to gyp variables.
if (is_asan) {
asan = "1"
} else {
asan = "0"
}
if (is_msan) {
msan = "1"
} else {
msan = "0"
}
if (is_tsan) {
tsan = "1"
} else {
tsan = "0"
}
if (is_cfi) {
cfi_vptr = "1"
} else {
cfi_vptr = "0"
}
if (target_cpu == "x86") {
target_arch = "ia32"
} else {
target_arch = target_cpu
}
if (is_debug) {
configuration_name = "Debug"
} else {
configuration_name = "Release"
}
if (is_component_build) {
component = "shared_library"
} else {
component = "static_library"
}
if (icu_use_data_file) {
icu_use_data_file_flag = "1"
} else {
icu_use_data_file_flag = "0"
}
if (v8_enable_inspector) {
enable_inspector = "1"
} else {
enable_inspector = "0"
}
if (v8_use_external_startup_data) {
use_external_startup_data = "1"
} else {
use_external_startup_data = "0"
}
if (v8_use_snapshot) {
use_snapshot = "true"
} else {
use_snapshot = "false"
}
if (v8_has_valgrind) {
has_valgrind = "1"
} else {
has_valgrind = "0"
}
if (v8_gcmole) {
gcmole = "1"
} else {
gcmole = "0"
}
# Note, all paths will be rebased in isolate_driver.py to be relative to
# the isolate file.
args = [
v8_test_isolation_mode,
"--isolated",
rebase_path("$root_out_dir/$name.isolated", root_build_dir),
"--isolate",
rebase_path(invoker.isolate, root_build_dir),
# Path variables are used to replace file paths when loading a .isolate
# file
"--path-variable",
"DEPTH",
rebase_path("//", root_build_dir),
"--path-variable",
"PRODUCT_DIR",
rebase_path(root_out_dir, root_build_dir),
# TODO(machenbach): Set variables for remaining features.
"--config-variable",
"CONFIGURATION_NAME=$configuration_name",
"--config-variable",
"OS=$target_os",
"--config-variable",
"asan=$asan",
"--config-variable",
"cfi_vptr=$cfi_vptr",
"--config-variable",
"gcmole=$gcmole",
"--config-variable",
"has_valgrind=$has_valgrind",
"--config-variable",
"icu_use_data_file_flag=$icu_use_data_file_flag",
"--config-variable",
"is_gn=1",
"--config-variable",
"msan=$msan",
"--config-variable",
"tsan=$tsan",
"--config-variable",
"coverage=0",
"--config-variable",
"sanitizer_coverage=0",
"--config-variable",
"component=$component",
"--config-variable",
"target_arch=$target_arch",
"--config-variable",
"v8_enable_inspector=$enable_inspector",
"--config-variable",
"v8_use_external_startup_data=$use_external_startup_data",
"--config-variable",
"v8_use_snapshot=$use_snapshot",
]
if (is_win) {
args += [
"--config-variable",
"msvs_version=2015",
]
} else {
args += [
"--config-variable",
"msvs_version=0",
]
}
}
}
}

12
samples/Genie/Class.gs Normal file
View File

@@ -0,0 +1,12 @@
init
new Demo( "Demonstration class" ).run()
class Demo
_message:string = ""
construct ( message:string = "Optional argument - no message passed in constructor" )
_message = message
def run()
print( _message )

2
samples/Genie/Hello.gs Normal file
View File

@@ -0,0 +1,2 @@
init
print( "Hello, World!" )

View File

@@ -0,0 +1,48 @@
{% from "forms.html" import label as description %}
{% macro field(name, value='', type='text') %}
<div class="field">
<input type="{{ type }}" name="{{ name }}"
value="{{ value | escape }}" />
</div>
{% endmacro %}
<html>
<head>
{% extends "head.html" %}
</head>
<body>
{% if horse %}
Chuck Norris once kicked a horse in the chin. Its descendants are known today as Giraffes.
{% elif optimus %}
Chuck Norris once urinated in a semi truck's gas tank as a joke....that truck is now known as Optimus Prime.
{% else %}
Chuck Norris threw a grenade and killed 50 people, then the grenade exploded.
{% endif %}
{% block left %}
This is the left side!
{% endblock %}
{% block right %}
This is the right side!
{% endblock %}
{{ description('Username') }}
{{ field('user') }}
{{ field('pass', type='password') }}
<h1>Posts</h1>
<ul>
{% for item in items %}
<li>{{ item.title }}</li>
{% else %}
<li>This would display if the 'item' collection were empty</li>
{% endfor %}
</ul>
{# Don't escape foo #}
{{ foo | safe }}
</body>
</html>

View File

@@ -0,0 +1,6 @@
{
"presets": [
"es2015",
"es2016"
]
}

View File

@@ -0,0 +1,923 @@
/* generated by jison-lex 0.3.4-159 */
var ccalcLex = (function () {
// See also:
// http://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/#35881508
// but we keep the prototype.constructor and prototype.name assignment lines too for compatibility
// with userland code which might access the derived class in a 'classic' way.
function JisonLexerError(msg, hash) {
Object.defineProperty(this, 'name', {
enumerable: false,
writable: false,
value: 'JisonLexerError'
});
if (msg == null) msg = '???';
Object.defineProperty(this, 'message', {
enumerable: false,
writable: true,
value: msg
});
this.hash = hash;
var stacktrace;
if (hash && hash.exception instanceof Error) {
var ex2 = hash.exception;
this.message = ex2.message || msg;
stacktrace = ex2.stack;
}
if (!stacktrace) {
if (Error.hasOwnProperty('captureStackTrace')) { // V8
Error.captureStackTrace(this, this.constructor);
} else {
stacktrace = (new Error(msg)).stack;
}
}
if (stacktrace) {
Object.defineProperty(this, 'stack', {
enumerable: false,
writable: false,
value: stacktrace
});
}
}
if (typeof Object.setPrototypeOf === 'function') {
Object.setPrototypeOf(JisonLexerError.prototype, Error.prototype);
} else {
JisonLexerError.prototype = Object.create(Error.prototype);
}
JisonLexerError.prototype.constructor = JisonLexerError;
JisonLexerError.prototype.name = 'JisonLexerError';
var lexer = {
EOF: 1,
ERROR: 2,
// JisonLexerError: JisonLexerError, // <-- injected by the code generator
// options: {}, // <-- injected by the code generator
// yy: ..., // <-- injected by setInput()
__currentRuleSet__: null, // <-- internal rule set cache for the current lexer state
__error_infos: [], // INTERNAL USE ONLY: the set of lexErrorInfo objects created since the last cleanup
__decompressed: false, // INTERNAL USE ONLY: mark whether the lexer instance has been 'unfolded' completely and is now ready for use
done: false, // INTERNAL USE ONLY
_backtrack: false, // INTERNAL USE ONLY
_input: '', // INTERNAL USE ONLY
_more: false, // INTERNAL USE ONLY
_signaled_error_token: false, // INTERNAL USE ONLY
conditionStack: [], // INTERNAL USE ONLY; managed via `pushState()`, `popState()`, `topState()` and `stateStackSize()`
match: '', // READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks input which has been matched so far for the lexer token under construction. `match` is identical to `yytext` except that this one still contains the matched input string after `lexer.performAction()` has been invoked, where userland code MAY have changed/replaced the `yytext` value entirely!
matched: '', // READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks entire input which has been matched so far
matches: false, // READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks RE match result for last (successful) match attempt
yytext: '', // ADVANCED USE ONLY: tracks input which has been matched so far for the lexer token under construction; this value is transferred to the parser as the 'token value' when the parser consumes the lexer token produced through a call to the `lex()` API.
offset: 0, // READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks the 'cursor position' in the input string, i.e. the number of characters matched so far
yyleng: 0, // READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: length of matched input for the token under construction (`yytext`)
yylineno: 0, // READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: 'line number' at which the token under construction is located
yylloc: null, // READ-ONLY EXTERNAL ACCESS - ADVANCED USE ONLY: tracks location info (lines + columns) for the token under construction
// INTERNAL USE: construct a suitable error info hash object instance for `parseError`.
constructLexErrorInfo: function lexer_constructLexErrorInfo(msg, recoverable) {
var pei = {
errStr: msg,
recoverable: !!recoverable,
text: this.match, // This one MAY be empty; userland code should use the `upcomingInput` API to obtain more text which follows the 'lexer cursor position'...
token: null,
line: this.yylineno,
loc: this.yylloc,
yy: this.yy,
lexer: this,
// and make sure the error info doesn't stay due to potential
// ref cycle via userland code manipulations.
// These would otherwise all be memory leak opportunities!
//
// Note that only array and object references are nuked as those
// constitute the set of elements which can produce a cyclic ref.
// The rest of the members is kept intact as they are harmless.
destroy: function destructLexErrorInfo() {
// remove cyclic references added to error info:
// info.yy = null;
// info.lexer = null;
// ...
var rec = !!this.recoverable;
for (var key in this) {
if (this.hasOwnProperty(key) && typeof key === 'object') {
this[key] = undefined;
}
}
this.recoverable = rec;
}
};
// track this instance so we can `destroy()` it once we deem it superfluous and ready for garbage collection!
this.__error_infos.push(pei);
return pei;
},
parseError: function lexer_parseError(str, hash) {
if (this.yy.parser && typeof this.yy.parser.parseError === 'function') {
return this.yy.parser.parseError(str, hash) || this.ERROR;
} else if (typeof this.yy.parseError === 'function') {
return this.yy.parseError.call(this, str, hash) || this.ERROR;
} else {
throw new this.JisonLexerError(str);
}
},
// final cleanup function for when we have completed lexing the input;
// make it an API so that external code can use this one once userland
// code has decided it's time to destroy any lingering lexer error
// hash object instances and the like: this function helps to clean
// up these constructs, which *may* carry cyclic references which would
// otherwise prevent the instances from being properly and timely
// garbage-collected, i.e. this function helps prevent memory leaks!
cleanupAfterLex: function lexer_cleanupAfterLex(do_not_nuke_errorinfos) {
var rv;
// prevent lingering circular references from causing memory leaks:
this.setInput('', {});
// nuke the error hash info instances created during this run.
// Userland code must COPY any data/references
// in the error hash instance(s) it is more permanently interested in.
if (!do_not_nuke_errorinfos) {
for (var i = this.__error_infos.length - 1; i >= 0; i--) {
var el = this.__error_infos[i];
if (el && typeof el.destroy === 'function') {
el.destroy();
}
}
this.__error_infos.length = 0;
}
return this;
},
// clear the lexer token context; intended for internal use only
clear: function lexer_clear() {
this.yytext = '';
this.yyleng = 0;
this.match = '';
this.matches = false;
this._more = false;
this._backtrack = false;
},
// resets the lexer, sets new input
setInput: function lexer_setInput(input, yy) {
this.yy = yy || this.yy || {};
// also check if we've fully initialized the lexer instance,
// including expansion work to be done to go from a loaded
// lexer to a usable lexer:
if (!this.__decompressed) {
// step 1: decompress the regex list:
var rules = this.rules;
for (var i = 0, len = rules.length; i < len; i++) {
var rule_re = rules[i];
// compression: is the RE an xref to another RE slot in the rules[] table?
if (typeof rule_re === 'number') {
rules[i] = rules[rule_re];
}
}
// step 2: unfold the conditions[] set to make these ready for use:
var conditions = this.conditions;
for (var k in conditions) {
var spec = conditions[k];
var rule_ids = spec.rules;
var len = rule_ids.length;
var rule_regexes = new Array(len + 1); // slot 0 is unused; we use a 1-based index approach here to keep the hottest code in `lexer_next()` fast and simple!
var rule_new_ids = new Array(len + 1);
if (this.rules_prefix1) {
var rule_prefixes = new Array(65536);
var first_catch_all_index = 0;
for (var i = 0; i < len; i++) {
var idx = rule_ids[i];
var rule_re = rules[idx];
rule_regexes[i + 1] = rule_re;
rule_new_ids[i + 1] = idx;
var prefix = this.rules_prefix1[idx];
// compression: is the PREFIX-STRING an xref to another PREFIX-STRING slot in the rules_prefix1[] table?
if (typeof prefix === 'number') {
prefix = this.rules_prefix1[prefix];
}
// init the prefix lookup table: first come, first serve...
if (!prefix) {
if (!first_catch_all_index) {
first_catch_all_index = i + 1;
}
} else {
for (var j = 0, pfxlen = prefix.length; j < pfxlen; j++) {
var pfxch = prefix.charCodeAt(j);
// first come, first serve:
if (!rule_prefixes[pfxch]) {
rule_prefixes[pfxch] = i + 1;
}
}
}
}
// if no catch-all prefix has been encountered yet, it means all
// rules have limited prefix sets and it MAY be that particular
// input characters won't be recognized by any rule in this
// condition state.
//
// To speed up their discovery at run-time while keeping the
// remainder of the lexer kernel code very simple (and fast),
// we point these to an 'illegal' rule set index *beyond*
// the end of the rule set.
if (!first_catch_all_index) {
first_catch_all_index = len + 1;
}
for (var i = 0; i < 65536; i++) {
if (!rule_prefixes[i]) {
rule_prefixes[i] = first_catch_all_index;
}
}
spec.__dispatch_lut = rule_prefixes;
} else {
for (var i = 0; i < len; i++) {
var idx = rule_ids[i];
var rule_re = rules[idx];
rule_regexes[i + 1] = rule_re;
rule_new_ids[i + 1] = idx;
}
}
spec.rules = rule_new_ids;
spec.__rule_regexes = rule_regexes;
spec.__rule_count = len;
}
this.__decompressed = true;
}
this._input = input || '';
this.clear();
this._signaled_error_token = false;
this.done = false;
this.yylineno = 0;
this.matched = '';
this.conditionStack = ['INITIAL'];
this.__currentRuleSet__ = null;
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (this.options.ranges) {
this.yylloc.range = [0, 0];
}
this.offset = 0;
return this;
},
// consumes and returns one char from the input
input: function lexer_input() {
if (!this._input) {
this.done = true;
return null;
}
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
// Count the linenumber up when we hit the LF (or a stand-alone CR).
// On CRLF, the linenumber is incremented when you fetch the CR or the CRLF combo
// and we advance immediately past the LF as well, returning both together as if
// it was all a single 'character' only.
var slice_len = 1;
var lines = false;
if (ch === '\n') {
lines = true;
} else if (ch === '\r') {
lines = true;
var ch2 = this._input[1];
if (ch2 === '\n') {
slice_len++;
ch += ch2;
this.yytext += ch2;
this.yyleng++;
this.offset++;
this.match += ch2;
this.matched += ch2;
if (this.options.ranges) {
this.yylloc.range[1]++;
}
}
}
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
} else {
this.yylloc.last_column++;
}
if (this.options.ranges) {
this.yylloc.range[1]++;
}
this._input = this._input.slice(slice_len);
return ch;
},
// unshifts one char (or a string) into the input
unput: function lexer_unput(ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - len);
this.matched = this.matched.substr(0, this.matched.length - len);
if (lines.length - 1) {
this.yylineno -= lines.length - 1;
}
this.yylloc.last_line = this.yylineno + 1;
this.yylloc.last_column = (lines ?
(lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ oldLines[oldLines.length - lines.length].length - lines[0].length :
this.yylloc.first_column - len);
if (this.options.ranges) {
this.yylloc.range[1] = this.yylloc.range[0] + this.yyleng - len;
}
this.yyleng = this.yytext.length;
this.done = false;
return this;
},
// When called from action, caches matched text and appends it on next action
more: function lexer_more() {
this._more = true;
return this;
},
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject: function lexer_reject() {
if (this.options.backtrack_lexer) {
this._backtrack = true;
} else {
// when the parseError() call returns, we MUST ensure that the error is registered.
// We accomplish this by signaling an 'error' token to be produced for the current
// .lex() run.
var p = this.constructLexErrorInfo('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), false);
this._signaled_error_token = (this.parseError(p.errStr, p) || this.ERROR);
}
return this;
},
// retain first n characters of the match
less: function lexer_less(n) {
return this.unput(this.match.slice(n));
},
// return (part of the) already matched input, i.e. for error messages.
// Limit the returned string length to `maxSize` (default: 20).
// Limit the returned string to the `maxLines` number of lines of input (default: 1).
// Negative limit values equal *unlimited*.
pastInput: function lexer_pastInput(maxSize, maxLines) {
var past = this.matched.substring(0, this.matched.length - this.match.length);
if (maxSize < 0)
maxSize = past.length;
else if (!maxSize)
maxSize = 20;
if (maxLines < 0)
maxLines = past.length; // can't ever have more input lines than this!
else if (!maxLines)
maxLines = 1;
// `substr` anticipation: treat \r\n as a single character and take a little
// more than necessary so that we can still properly check against maxSize
// after we've transformed and limited the newLines in here:
past = past.substr(-maxSize * 2 - 2);
// now that we have a significantly reduced string to process, transform the newlines
// and chop them, then limit them:
var a = past.replace(/\r\n|\r/g, '\n').split('\n');
a = a.slice(-maxLines);
past = a.join('\n');
// When, after limiting to maxLines, we still have too much to return,
// do add an ellipsis prefix...
if (past.length > maxSize) {
past = '...' + past.substr(-maxSize);
}
return past;
},
// return (part of the) upcoming input, i.e. for error messages.
// Limit the returned string length to `maxSize` (default: 20).
// Limit the returned string to the `maxLines` number of lines of input (default: 1).
// Negative limit values equal *unlimited*.
upcomingInput: function lexer_upcomingInput(maxSize, maxLines) {
var next = this.match;
if (maxSize < 0)
maxSize = next.length + this._input.length;
else if (!maxSize)
maxSize = 20;
if (maxLines < 0)
maxLines = maxSize; // can't ever have more input lines than this!
else if (!maxLines)
maxLines = 1;
// `substring` anticipation: treat \r\n as a single character and take a little
// more than necessary so that we can still properly check against maxSize
// after we've transformed and limited the newLines in here:
if (next.length < maxSize * 2 + 2) {
next += this._input.substring(0, maxSize * 2 + 2); // substring is faster on Chrome/V8
}
// now that we have a significantly reduced string to process, transform the newlines
// and chop them, then limit them:
var a = next.replace(/\r\n|\r/g, '\n').split('\n');
a = a.slice(0, maxLines);
next = a.join('\n');
// When, after limiting to maxLines, we still have too much to return,
// do add an ellipsis postfix...
if (next.length > maxSize) {
next = next.substring(0, maxSize) + '...';
}
return next;
},
// return a string which displays the character position where the lexing error occurred, i.e. for error messages
showPosition: function lexer_showPosition(maxPrefix, maxPostfix) {
var pre = this.pastInput(maxPrefix).replace(/\s/g, ' ');
var c = new Array(pre.length + 1).join('-');
return pre + this.upcomingInput(maxPostfix).replace(/\s/g, ' ') + '\n' + c + '^';
},
// helper function, used to produce a human readable description as a string, given
// the input `yylloc` location object.
// Set `display_range_too` to TRUE to include the string character index position(s)
// in the description if the `yylloc.range` is available.
describeYYLLOC: function lexer_describe_yylloc(yylloc, display_range_too) {
var l1 = yylloc.first_line;
var l2 = yylloc.last_line;
var o1 = yylloc.first_column;
var o2 = yylloc.last_column - 1;
var dl = l2 - l1;
var d_o = (dl === 0 ? o2 - o1 : 1000);
var rv;
if (dl === 0) {
rv = 'line ' + l1 + ', ';
if (d_o === 0) {
rv += 'column ' + o1;
} else {
rv += 'columns ' + o1 + ' .. ' + o2;
}
} else {
rv = 'lines ' + l1 + '(column ' + o1 + ') .. ' + l2 + '(column ' + o2 + ')';
}
if (yylloc.range && display_range_too) {
var r1 = yylloc.range[0];
var r2 = yylloc.range[1] - 1;
if (r2 === r1) {
rv += ' {String Offset: ' + r1 + '}';
} else {
rv += ' {String Offset range: ' + r1 + ' .. ' + r2 + '}';
}
}
return rv;
// return JSON.stringify(yylloc);
},
// test the lexed token: return FALSE when not a match, otherwise return token.
//
// `match` is supposed to be an array coming out of a regex match, i.e. `match[0]`
// contains the actually matched text string.
//
// Also move the input cursor forward and update the match collectors:
// - yytext
// - yyleng
// - match
// - matches
// - yylloc
// - offset
test_match: function lexer_test_match(match, indexed_rule) {
var token,
lines,
backup,
match_str;
if (this.options.backtrack_lexer) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
matched: this.matched,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
_input: this._input,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (this.options.ranges) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
match_str = match[0];
lines = match_str.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno += lines.length;
}
this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ?
lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
this.yylloc.last_column + match_str.length
};
this.yytext += match_str;
this.match += match_str;
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset + this.yyleng];
}
// previous lex rules MAY have invoked the `more()` API rather than producing a token:
// those rules will already have moved this `offset` forward matching their match lengths,
// hence we must only add our own match length now:
this.offset += match_str.length;
this._more = false;
this._backtrack = false;
this._input = this._input.slice(match_str.length);
this.matched += match_str;
// calling this method:
//
// function lexer__performAction(yy, yy_, $avoiding_name_collisions, YY_START) {...}
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1] /* = YY_START */);
// otherwise, when the action codes are all simple return token statements:
//token = this.simpleCaseActionClusters[indexed_rule];
if (this.done && this._input) {
this.done = false;
}
if (token) {
return token;
} else if (this._backtrack) {
// recover context
for (var k in backup) {
this[k] = backup[k];
}
this.__currentRuleSet__ = null;
return false; // rule action called reject() implying the next rule should be tested instead.
} else if (this._signaled_error_token) {
// produce one 'error' token as .parseError() in reject() did not guarantee a failure signal by throwing an exception!
token = this._signaled_error_token;
this._signaled_error_token = false;
return token;
}
return false;
},
// return next match in input
next: function lexer_next() {
if (this.done) {
this.clear();
return this.EOF;
}
if (!this._input) {
this.done = true;
}
var token,
match,
tempMatch,
index;
if (!this._more) {
this.clear();
}
var spec = this.__currentRuleSet__;
if (!spec) {
// Update the ruleset cache as we apparently encountered a state change or just started lexing.
// The cache is set up for fast lookup -- we assume a lexer will switch states much less often than it will
// invoke the `lex()` token-producing API and related APIs, hence caching the set for direct access helps
// speed up those activities a tiny bit.
spec = this.__currentRuleSet__ = this._currentRules();
}
var rule_ids = spec.rules;
// var dispatch = spec.__dispatch_lut;
var regexes = spec.__rule_regexes;
var len = spec.__rule_count;
// var c0 = this._input[0];
// Note: the arrays are 1-based, while `len` itself is a valid index,
// hence the non-standard less-or-equal check in the next loop condition!
//
// `dispatch` is a lookup table which lists the *first* rule which matches the 1-char *prefix* of the rule-to-match.
// By using that array as a jumpstart, we can cut down on the otherwise O(n*m) behaviour of this lexer, down to
// O(n) ideally, where:
//
// - N is the number of input particles -- which is not precisely characters
// as we progress on a per-regex-match basis rather than on a per-character basis
//
// - M is the number of rules (regexes) to test in the active condition state.
//
for (var i = 1 /* (dispatch[c0] || 1) */ ; i <= len; i++) {
tempMatch = this._input.match(regexes[i]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (this.options.backtrack_lexer) {
token = this.test_match(tempMatch, rule_ids[i]);
if (token !== false) {
return token;
} else if (this._backtrack) {
match = undefined;
continue; // rule action called reject() implying a rule MISmatch.
} else {
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
} else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rule_ids[index]);
if (token !== false) {
return token;
}
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
if (this._input === '') {
this.done = true;
return this.EOF;
} else {
var p = this.constructLexErrorInfo('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), this.options.lexer_errors_are_recoverable);
token = (this.parseError(p.errStr, p) || this.ERROR);
if (token === this.ERROR) {
// we can try to recover from a lexer error that parseError() did not 'recover' for us, by moving forward at least one character at a time:
if (!this.match.length) {
this.input();
}
}
return token;
}
},
// return next match that has a token
lex: function lexer_lex() {
var r;
// allow the PRE/POST handlers set/modify the return token for maximum flexibility of the generated lexer:
if (typeof this.options.pre_lex === 'function') {
r = this.options.pre_lex.call(this);
}
while (!r) {
r = this.next();
}
if (typeof this.options.post_lex === 'function') {
// (also account for a userdef function which does not return any value: keep the token as is)
r = this.options.post_lex.call(this, r) || r;
}
return r;
},
// backwards compatible alias for `pushState()`;
// the latter is symmetrical with `popState()` and we advise to use
// those APIs in any modern lexer code, rather than `begin()`.
begin: function lexer_begin(condition) {
return this.pushState(condition);
},
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
pushState: function lexer_pushState(condition) {
this.conditionStack.push(condition);
this.__currentRuleSet__ = null;
return this;
},
// pop the previously active lexer condition state off the condition stack
popState: function lexer_popState() {
var n = this.conditionStack.length - 1;
if (n > 0) {
this.__currentRuleSet__ = null;
return this.conditionStack.pop();
} else {
return this.conditionStack[0];
}
},
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState: function lexer_topState(n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
if (n >= 0) {
return this.conditionStack[n];
} else {
return 'INITIAL';
}
},
// (internal) determine the lexer rule set which is active for the currently active lexer condition state
_currentRules: function lexer__currentRules() {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]];
} else {
return this.conditions['INITIAL'];
}
},
// return the number of states currently on the stack
stateStackSize: function lexer_stateStackSize() {
return this.conditionStack.length;
},
options: {},
JisonLexerError: JisonLexerError,
performAction: function lexer__performAction(yy, yy_, $avoiding_name_collisions, YY_START) {
var YYSTATE = YY_START;
switch($avoiding_name_collisions) {
case 0 :
/*! Conditions:: INITIAL */
/*! Rule:: [ \t\r\n]+ */
/* eat up whitespace */
BeginToken(yy_.yytext);
break;
case 1 :
/*! Conditions:: INITIAL */
/*! Rule:: {DIGIT}+ */
BeginToken(yy_.yytext);
yylval.value = atof(yy_.yytext);
return VALUE;
break;
case 2 :
/*! Conditions:: INITIAL */
/*! Rule:: {DIGIT}+\.{DIGIT}* */
BeginToken(yy_.yytext);
yylval.value = atof(yy_.yytext);
return VALUE;
break;
case 3 :
/*! Conditions:: INITIAL */
/*! Rule:: {DIGIT}+[eE]["+""-"]?{DIGIT}* */
BeginToken(yy_.yytext);
yylval.value = atof(yy_.yytext);
return VALUE;
break;
case 4 :
/*! Conditions:: INITIAL */
/*! Rule:: {DIGIT}+\.{DIGIT}*[eE]["+""-"]?{DIGIT}* */
BeginToken(yy_.yytext);
yylval.value = atof(yy_.yytext);
return VALUE;
break;
case 5 :
/*! Conditions:: INITIAL */
/*! Rule:: {ID} */
BeginToken(yy_.yytext);
yylval.string = malloc(strlen(yy_.yytext)+1);
strcpy(yylval.string, yy_.yytext);
return IDENTIFIER;
break;
case 6 :
/*! Conditions:: INITIAL */
/*! Rule:: \+ */
BeginToken(yy_.yytext); return ADD;
break;
case 7 :
/*! Conditions:: INITIAL */
/*! Rule:: - */
BeginToken(yy_.yytext); return SUB;
break;
case 8 :
/*! Conditions:: INITIAL */
/*! Rule:: \* */
BeginToken(yy_.yytext); return MULT;
break;
case 9 :
/*! Conditions:: INITIAL */
/*! Rule:: \/ */
BeginToken(yy_.yytext); return DIV;
break;
case 10 :
/*! Conditions:: INITIAL */
/*! Rule:: \( */
BeginToken(yy_.yytext); return LBRACE;
break;
case 11 :
/*! Conditions:: INITIAL */
/*! Rule:: \) */
BeginToken(yy_.yytext); return RBRACE;
break;
case 12 :
/*! Conditions:: INITIAL */
/*! Rule:: ; */
BeginToken(yy_.yytext); return SEMICOLON;
break;
case 13 :
/*! Conditions:: INITIAL */
/*! Rule:: = */
BeginToken(yy_.yytext); return ASSIGN;
break;
case 14 :
/*! Conditions:: INITIAL */
/*! Rule:: . */
BeginToken(yy_.yytext);
return yy_.yytext[0];
break;
default:
return this.simpleCaseActionClusters[$avoiding_name_collisions];
}
},
simpleCaseActionClusters: {
},
rules: [
/^(?:[ \t\r\n]+)/,
/^(?:(\d)+)/,
/^(?:(\d)+\.(\d)*)/,
/^(?:(\d)+[Ee]["+]?(\d)*)/,
/^(?:(\d)+\.(\d)*[Ee]["+]?(\d)*)/,
/^(?:([^\W\d]\w*))/,
/^(?:\+)/,
/^(?:-)/,
/^(?:\*)/,
/^(?:\/)/,
/^(?:\()/,
/^(?:\))/,
/^(?:;)/,
/^(?:=)/,
/^(?:.)/
],
conditions: {
"INITIAL": {
rules: [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14
],
inclusive: true
}
}
};
/*--------------------------------------------------------------------
* lex.l
*------------------------------------------------------------------*/;
return lexer;
})();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
/**
* @fileoverview
* @enhanceable
* @public
*/
// GENERATED CODE -- DO NOT EDIT!
goog.provide('proto.google.protobuf.Timestamp');
goog.require('jspb.Message');
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
* server response, or constructed directly in Javascript. The array is used
* in place and becomes part of the constructed object. It is not cloned.
* If no data is provided, the constructed object will be empty, but still
* valid.
* @extends {jspb.Message}
* @constructor
*/
proto.google.protobuf.Timestamp = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.google.protobuf.Timestamp, jspb.Message);
if (goog.DEBUG && !COMPILED) {
proto.google.protobuf.Timestamp.displayName = 'proto.google.protobuf.Timestamp';
}
// Remainder elided

View File

@@ -0,0 +1,49 @@
- label: 'desired label name'
- connection: connection_name
- include: filename_or_pattern
# Possibly more include declarations
- persist_for: N (seconds | minutes | hours)
- case_sensitive: true | false
- week_start_day: monday | tuesday | wednesday | thursday | friday | saturday | sunday
- value_formats:
- name: desired_format_name
value_format: 'excel-style formatting string'
# Possibly more value formats
- explore: view_name
label: 'desired label name'
description: 'description string'
symmetric_aggregates: true | false
hidden: true | false
fields: [field_or_set, field_or_set, …]
sql_always_where: SQL WHERE condition
always_filter:
field_name: 'looker filter expression'
conditionally_filter:
field_name: 'looker filter expression'
unless: [field_or_set, field_or_set, …]
access_filter_fields: [fully_scoped_field, fully_scoped_field, …]
always_join: [view_name, view_name, …]
joins:
- join: view_name
type: left_outer | full_outer | inner | cross
relationship: one_to_one | many_to_one | one_to_many | many_to_many
from: view_name
sql_table_name: table_name
view_label: 'desired label name'
fields: [field_or_set, field_or_set, …]
required_joins: [view_name, view_name, …]
foreign_key: dimension_name
sql_on: SQL ON clause
# Possibly more join declarations
persist_for: N (seconds | minutes | hours)
from: view_name
view: view_name
case_sensitive: true | false
sql_table_name: table_name
cancel_grouping_fields: [fully_scoped_field, fully_scoped_field, …]
# Possibly more explore declarations

View File

@@ -0,0 +1,90 @@
- view: view_name
sql_table_name: table_name
suggestions: true | false
derived_table:
sql: SQL query
persist_for: N (seconds | minutes | hours)
sql_trigger_value: SQL query
distribution: column_name
distribution_style: ALL | EVEN
sortkeys: [column_name, column_name, …]
indexes: [column_name, column_name, …]
sets:
set_name:
- field_or_set
- field_or_set
- …
# Possibly more set declarations
fields:
- (dimension | dimension_group | measure | filter): field_name
label: 'desired label name'
view_label: 'desired label name'
group_label: 'desired label name'
description: 'description string'
hidden: true | false
alias: [old_field_name, old_field_name, …]
value_format: 'excel-style formatting string'
value_format_name: format_name
html: HTML expression using Liquid template elements
sql: SQL expression to generate the field value
required_fields: [field_name, field_name, …]
drill_fields: [field_or_set, field_or_set, …]
can_filter: true | false
fanout_on: repeated_record_name
# DIMENSION SPECIFIC PARAMETERS
type: dimension_field_type
primary_key: true | false
sql_case:
value: SQL condition
value: SQL condition
# Possibly more sql_case statements
alpha_sort: true | false
tiers: [N, N, …]
style: classic | interval | integer | relational
sql_latitude: SQL expression to generate a latitude
sql_longitude: SQL expression to generate a longitude
suggestable: true | false
suggest_persist_for: N (seconds | minutes | hours)
suggest_dimension: dimension_name
suggest_explore: explore_name
suggestions: ['suggestion string', 'suggestion string', …]
bypass_suggest_restrictions: true | false
full_suggestions: true | false
skip_drill_filter: true | false
case_sensitive: true | false
order_by_field: dimension_name
map_layer: name_of_map_layer
links:
- label: 'desired label name'
url: desired_url
icon_url: url_of_an_ico_file
# Possibly more links
# DIMENSION GROUP SPECIFIC PARAMETERS
timeframes: [timeframe, timeframe, …]
convert_tz: true | false
datatype: epoch | timestamp | datetime | date | yyyymmdd
# MEASURE SPECIFIC PARAMETERS
type: measure_field_type
direction: row | column
approximate: true | false
approximate_threshold: N
sql_distinct_key: SQL expression to define repeated entities
list_field: dimension_name
filters:
dimension_name: 'looker filter expression'
# Possibly more filters statements
# FILTER SPECIFIC PARAMETERS
default_value: 'desired default value'
# Possibly more dimension or measure declarations

View File

@@ -0,0 +1,93 @@
<?php
namespace github\com;
/**
* Autogenerated by Thrift Compiler (0.9.3)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
use Thrift\Base\TBase;
use Thrift\Type\TType;
use Thrift\Type\TMessageType;
use Thrift\Exception\TException;
use Thrift\Exception\TProtocolException;
use Thrift\Protocol\TProtocol;
use Thrift\Protocol\TBinaryProtocolAccelerated;
use Thrift\Exception\TApplicationException;
class PullRequest {
static $_TSPEC;
/**
* @var string
*/
public $title = null;
public function __construct($vals=null) {
if (!isset(self::$_TSPEC)) {
self::$_TSPEC = array(
1 => array(
'var' => 'title',
'type' => TType::STRING,
),
);
}
if (is_array($vals)) {
if (isset($vals['title'])) {
$this->title = $vals['title'];
}
}
}
public function getName() {
return 'PullRequest';
}
public function read($input)
{
$xfer = 0;
$fname = null;
$ftype = 0;
$fid = 0;
$xfer += $input->readStructBegin($fname);
while (true)
{
$xfer += $input->readFieldBegin($fname, $ftype, $fid);
if ($ftype == TType::STOP) {
break;
}
switch ($fid)
{
case 1:
if ($ftype == TType::STRING) {
$xfer += $input->readString($this->title);
} else {
$xfer += $input->skip($ftype);
}
break;
default:
$xfer += $input->skip($ftype);
break;
}
$xfer += $input->readFieldEnd();
}
$xfer += $input->readStructEnd();
return $xfer;
}
public function write($output) {
$xfer = 0;
$xfer += $output->writeStructBegin('PullRequest');
if ($this->title !== null) {
$xfer += $output->writeFieldBegin('title', TType::STRING, 1);
$xfer += $output->writeString($this->title);
$xfer += $output->writeFieldEnd();
}
$xfer += $output->writeFieldStop();
$xfer += $output->writeStructEnd();
return $xfer;
}
}

View File

@@ -0,0 +1,37 @@
<?php
$header = <<<'EOF'
This file is part of PHP CS Fixer.
(c) Fabien Potencier <fabien@symfony.com>
Dariusz Rumiński <dariusz.ruminski@gmail.com>
This source file is subject to the MIT license that is bundled
with this source code in the file LICENSE.
EOF;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(array(
'@Symfony' => true,
'@Symfony:risky' => true,
'combine_consecutive_unsets' => true,
'header_comment' => array('header' => $header),
'array_syntax' => array('syntax' => 'long'),
'no_extra_consecutive_blank_lines' => array('break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block'),
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'php_unit_strict' => true,
'phpdoc_add_missing_param_annotation' => true,
'psr4' => true,
'strict_comparison' => true,
'strict_param' => true,
))
->setFinder(
PhpCsFixer\Finder::create()
->exclude('tests/Fixtures')
->in(__DIR__)
)
;

View File

@@ -0,0 +1,37 @@
<?php
$header = <<<'EOF'
This file is part of PHP CS Fixer.
(c) Fabien Potencier <fabien@symfony.com>
Dariusz Rumiński <dariusz.ruminski@gmail.com>
This source file is subject to the MIT license that is bundled
with this source code in the file LICENSE.
EOF;
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(array(
'@Symfony' => true,
'@Symfony:risky' => true,
'combine_consecutive_unsets' => true,
'header_comment' => array('header' => $header),
'array_syntax' => array('syntax' => 'long'),
'no_extra_consecutive_blank_lines' => array('break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block'),
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'php_unit_strict' => true,
'phpdoc_add_missing_param_annotation' => true,
'psr4' => true,
'strict_comparison' => true,
'strict_param' => true,
))
->setFinder(
PhpCsFixer\Finder::create()
->exclude('tests/Fixtures')
->in(__DIR__)
)
;

View File

@@ -0,0 +1,9 @@
solutions = [
{
"url": "https://chromium.googlesource.com/v8/v8.git",
"managed": False,
"name": "v8",
"deps_file": "DEPS",
"custom_deps": {},
},
]

20
samples/Python/py3.py3 Normal file
View File

@@ -0,0 +1,20 @@
import random
guesses = 0
number = random.randint(1, 20)
print("Guess the number between 1 and 20! You have 6 tries.")
while guesses < 6:
guess = int(input("Is it... "))
if guess == number:
print("Hooray! You guessed it right!")
break
elif guess < number:
print("It's bigger...")
elif guess > number:
print("It's not so big.")
guesses += 1
if guesses == 6:
print("You've ran out of tries.")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

72
samples/R/import.Rd Normal file
View File

@@ -0,0 +1,72 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/hello.R
\name{import}
\alias{import}
\title{Import a module into the current scope}
\usage{
import(module, attach, attach_operators = TRUE)
}
\arguments{
\item{module}{an identifier specifying the full module path}
\item{attach}{if \code{TRUE}, attach the newly loaded module to the object
search path (see \code{Details})}
\item{attach_operators}{if \code{TRUE}, attach operators of module to the
object search path, even if \code{attach} is \code{FALSE}}
}
\value{
the loaded module environment (invisible)
}
\description{
\code{module = import('module')} imports a specified module and makes its
code available via the environment-like object it returns.
}
\details{
Modules are loaded in an isolated environment which is returned, and
optionally attached to the object search path of the current scope (if
argument \code{attach} is \code{TRUE}).
\code{attach} defaults to \code{FALSE}. However, in interactive code it is
often helpful to attach packages by default. Therefore, in interactive code
invoked directly from the terminal only (i.e. not within modules),
\code{attach} defaults to the value of \code{options('import.attach')}, which
can be set to \code{TRUE} or \code{FALSE} depending on the users preference.
\code{attach_operators} causes \emph{operators} to be attached by default,
because operators can only be invoked in R if they re found in the search
path. Not attaching them therefore drastically limits a modules usefulness.
Modules are searched in the module search path \code{options('import.path')}.
This is a vector of paths to consider, from the highest to the lowest
priority. The current directory is \emph{always} considered first. That is,
if a file \code{a.r} exists both in the current directory and in a module
search path, the local file \code{./a.r} will be loaded.
Module names can be fully qualified to refer to nested paths. See
\code{Examples}.
}
\note{
Unlike for packages, attaching happens \emph{locally}: if
\code{import} is executed in the global environment, the effect is the same.
Otherwise, the imported module is inserted as the parent of the current
\code{environment()}. When used (globally) \emph{inside} a module, the newly
imported module is only available inside the modules search path, not
outside it (nor in other modules which might be loaded).
}
\examples{
# `a.r` is a file in the local directory containing a function `f`.
a = import('a')
a$f()
# b/c.r is a file in path `b`, containing a function `g`.
import('b/c', attach = TRUE)
g() # No module name qualification necessary
}
\seealso{
\code{unload}
\code{reload}
\code{module_name}
}

View File

@@ -0,0 +1,10 @@
module Analyze
import Syntax;
set[Id] unreachable(Machine m) {
r = { <q1,q2> | (State)`state <Id q1> <Trans* ts>` <- m.states,
(Trans)`<Id _>: <Id q2>` <- ts }+;
qs = [ q.name | /State q := m ];
return { q | q <- qs, q notin r[qs[0]] };
}

View File

@@ -0,0 +1,18 @@
module Compile
import Syntax;
str compile(Machine m) =
"while (true) {
' event = input.next();
' switch (current) {
' <for (q <- m.states) {>
' case \"<q.name>\":
' <for (t <- q.out) {>
' if (event.equals(\"<t.event>\"))
' current = \"<t.to>\";
' <}>
' break;
' <}>
' }
'}";

887
samples/Rascal/Rascal.rsc Normal file
View File

@@ -0,0 +1,887 @@
@license{
Copyright (c) 2009-2015 CWI
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
}
@contributor{Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI}
@contributor{Tijs van der Storm - Tijs.van.der.Storm@cwi.nl}
@contributor{Paul Klint - Paul.Klint@cwi.nl - CWI}
@contributor{Arnold Lankamp - Arnold.Lankamp@cwi.nl}
@contributor{Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI}
@doc{The syntax definition of Rascal, excluding concrete syntax fragments}
module lang::rascal::\syntax::Rascal
lexical BooleanLiteral
= "true"
| "false" ;
syntax Literal
= integer: IntegerLiteral integerLiteral
| regExp: RegExpLiteral regExpLiteral
| \real: RealLiteral realLiteral
| boolean: BooleanLiteral booleanLiteral
| string: StringLiteral stringLiteral
| dateTime: DateTimeLiteral dateTimeLiteral
| location: LocationLiteral locationLiteral
| rational: RationalLiteral rationalLiteral
;
syntax Expression = concrete: Concrete concrete;
syntax Pattern = concrete: Concrete concrete;
lexical Concrete
= typed: "(" LAYOUTLIST l1 Sym symbol LAYOUTLIST l2 ")" LAYOUTLIST l3 "`" ConcretePart* parts "`";
lexical ConcretePart
= @category="MetaSkipped" text : ![`\<\>\\\n]+ !>> ![`\<\>\\\n]
| newline: "\n" [\ \t \u00A0 \u1680 \u2000-\u200A \u202F \u205F \u3000]* "\'"
| @category="MetaVariable" hole : ConcreteHole hole
| @category="MetaSkipped" lt: "\\\<"
| @category="MetaSkipped" gt: "\\\>"
| @category="MetaSkipped" bq: "\\`"
| @category="MetaSkipped" bs: "\\\\"
;
syntax ConcreteHole
= \one: "\<" Sym symbol Name name "\>"
;
start syntax Module
= \default: Header header Body body ;
syntax ModuleParameters
= \default: "[" {TypeVar ","}+ parameters "]" ;
lexical DateAndTime
= "$" DatePart "T" TimePartNoTZ !>> [+\-] "$"
| "$" DatePart "T" TimePartNoTZ TimeZonePart "$";
syntax Strategy
= topDownBreak: "top-down-break"
| topDown: "top-down"
| bottomUp: "bottom-up"
| bottomUpBreak: "bottom-up-break"
| outermost: "outermost"
| innermost: "innermost" ;
lexical UnicodeEscape
= utf16: "\\" [u] [0-9 A-F a-f] [0-9 A-F a-f] [0-9 A-F a-f] [0-9 A-F a-f]
| utf32: "\\" [U] (("0" [0-9 A-F a-f]) | "10") [0-9 A-F a-f] [0-9 A-F a-f] [0-9 A-F a-f] [0-9 A-F a-f] // 24 bits
| ascii: "\\" [a] [0-7] [0-9A-Fa-f]
;
syntax Variable
= initialized: Name name "=" Expression initial
| unInitialized: Name name ;
lexical OctalIntegerLiteral
= [0] [0-7]+ !>> [0-9 A-Z _ a-z] ;
syntax TypeArg
= \default: Type type
| named: Type type Name name ;
syntax Renaming
= \default: Name from "=\>" Name to ;
syntax Catch
= \default: "catch" ":" Statement body
| binding: "catch" Pattern pattern ":" Statement body ;
lexical PathChars
= URLChars [|] ;
syntax Signature
= withThrows: FunctionModifiers modifiers Type type Name name Parameters parameters "throws" {Type ","}+ exceptions
| noThrows: FunctionModifiers modifiers Type type Name name Parameters parameters ;
syntax Sym
// named non-terminals
= nonterminal: Nonterminal nonterminal !>> "["
| parameter: "&" Nonterminal nonterminal
| parametrized: Nonterminal nonterminal >> "[" "[" {Sym ","}+ parameters "]"
| \start: "start" "[" Nonterminal nonterminal "]"
| labeled: Sym symbol NonterminalLabel label
// literals
| characterClass: Class charClass
| literal: StringConstant string
| caseInsensitiveLiteral: CaseInsensitiveStringConstant cistring
// regular expressions
| iter: Sym symbol "+"
| iterStar: Sym symbol "*"
| iterSep: "{" Sym symbol Sym sep "}" "+"
| iterStarSep: "{" Sym symbol Sym sep "}" "*"
| optional: Sym symbol "?"
| alternative: "(" Sym first "|" {Sym "|"}+ alternatives ")"
| sequence: "(" Sym first Sym+ sequence ")"
// TODO: MinimalIter: Sym symbol IntegerConstant minimal "+"
// TODO: MinimalIterSep: "{" Sym symbol Symbol sep "}" IntegerConstant minimal "+"
// TODO | Permutation: "(" Sym first "~" {Sym "~"}+ participants ")"
// TODO | Combination: "(" Sym first "#" {Sym "#"}+ elements ")"
| empty: "(" ")"
// conditionals
| column: Sym symbol "@" IntegerLiteral column
| endOfLine: Sym symbol "$"
| startOfLine: "^" Sym symbol
| except: Sym symbol "!" NonterminalLabel label
>
assoc (
left ( follow: Sym symbol "\>\>" Sym match
| notFollow: Sym symbol "!\>\>" Sym match
)
|
right ( precede: Sym match "\<\<" Sym symbol
| notPrecede: Sym match "!\<\<" Sym symbol
)
)
>
left unequal: Sym symbol "\\" Sym match
;
lexical TimePartNoTZ
= [0-2] [0-9] [0-5] [0-9] [0-5] [0-9] ([, .] [0-9] ([0-9] [0-9]?)?)?
| [0-2] [0-9] ":" [0-5] [0-9] ":" [0-5] [0-9] ([, .] [0-9] ([0-9] [0-9]?)?)?
;
syntax Header
= parameters: Tags tags "module" QualifiedName name ModuleParameters params Import* imports
| \default: Tags tags "module" QualifiedName name Import* imports ;
lexical Name
// Names are surrounded by non-alphabetical characters, i.e. we want longest match.
= ([A-Z a-z _] !<< [A-Z _ a-z] [0-9 A-Z _ a-z]* !>> [0-9 A-Z _ a-z]) \ RascalKeywords
| [\\] [A-Z _ a-z] [\- 0-9 A-Z _ a-z]* !>> [\- 0-9 A-Z _ a-z]
;
syntax SyntaxDefinition
= @Foldable \layout : Visibility vis "layout" Sym defined "=" Prod production ";"
| @Foldable \lexical : "lexical" Sym defined "=" Prod production ";"
| @Foldable \keyword : "keyword" Sym defined "=" Prod production ";"
| @Foldable language: Start start "syntax" Sym defined "=" Prod production ";" ;
syntax Kind
= function: "function"
| variable: "variable"
| \all: "all"
| \anno: "anno"
| \data: "data"
| view: "view"
| \alias: "alias"
| \module: "module"
| \tag: "tag" ;
syntax ImportedModule
= \default: QualifiedName name
| actualsRenaming: QualifiedName name ModuleActuals actuals Renamings renamings
| renamings: QualifiedName name Renamings renamings
| actuals: QualifiedName name ModuleActuals actuals
;
syntax Target
= empty:
| labeled: Name name ;
syntax IntegerLiteral
= /*prefer()*/ decimalIntegerLiteral: DecimalIntegerLiteral decimal
| /*prefer()*/ hexIntegerLiteral: HexIntegerLiteral hex
| /*prefer()*/ octalIntegerLiteral: OctalIntegerLiteral octal ;
syntax FunctionBody
= \default: "{" Statement* statements "}" ;
syntax Expression
= nonEmptyBlock : "{" Statement+ statements "}"
| bracket \bracket: "(" Expression expression ")"
| closure : Type type Parameters parameters "{" Statement+ statements "}"
| stepRange : "[" Expression first "," Expression second ".." Expression last "]"
| voidClosure : Parameters parameters "{" Statement* statements0 "}"
| \visit : Label label Visit visit
| reducer : "(" Expression init "|" Expression result "|" {Expression ","}+ generators ")"
| reifiedType : "type" "(" Expression symbol "," Expression definitions ")"
| callOrTree : Expression!transitiveClosure!transitiveReflexiveClosure!isDefined expression "(" {Expression ","}* arguments KeywordArguments[Expression] keywordArguments ")"
| literal : Literal literal
| \any : "any" "(" {Expression ","}+ generators ")"
| \all : "all" "(" {Expression ","}+ generators ")"
| comprehension : Comprehension comprehension
| \set : "{" {Expression ","}* elements0 "}"
| \list : "[" {Expression ","}* elements0 "]"
| reifyType : "#" Type type !>> "[" !selector
| range : "[" Expression first ".." Expression last "]"
| \tuple : "\<" {Expression ","}+ elements "\>"
| \map : "(" {Mapping[Expression] ","}* mappings ")"
| \it : [A-Z a-z _] !<< "it" !>> [A-Z a-z _]
| qualifiedName : QualifiedName qualifiedName
| subscript : Expression expression!transitiveClosure!transitiveReflexiveClosure!isDefined "[" {Expression ","}+ subscripts "]"
| slice : Expression expression!transitiveClosure!transitiveReflexiveClosure!isDefined "[" OptionalExpression optFirst ".." OptionalExpression optLast "]"
| sliceStep : Expression expression!transitiveClosure!transitiveReflexiveClosure!isDefined "[" OptionalExpression optFirst "," Expression second ".." OptionalExpression optLast "]"
| fieldAccess : Expression expression "." Name field
| fieldUpdate : Expression expression "[" Name key "=" Expression replacement "]"
| fieldProject : Expression expression!transitiveClosure!transitiveReflexiveClosure!isDefined "\<" {Field ","}+ fields "\>"
| setAnnotation: Expression expression "[" "@" Name name "=" Expression value "]"
| getAnnotation: Expression expression >> "@" "@" Name name
| is : Expression expression "is" Name name
| has : Expression expression "has" Name name
| transitiveClosure: Expression argument "+" !>> "="
| transitiveReflexiveClosure: Expression argument "*" !>> "="
> isDefined : Expression argument "?"
> negation : "!" Expression!match!noMatch argument
| negative : "-" Expression argument
| non-assoc splice : "*" Expression argument
| asType : "[" Type type "]" Expression!match!noMatch argument
> left composition: Expression lhs "o" Expression rhs
> left ( product: Expression lhs "*" () !>> "*" Expression!noMatch!match rhs
| \join : Expression lhs "join" Expression rhs
| remainder: Expression lhs "%" Expression rhs
| division: Expression lhs "/" Expression rhs
)
> left intersection: Expression lhs "&" !>> "&" Expression rhs
> left ( addition : Expression lhs "+" Expression!noMatch!match rhs
| subtraction: Expression!transitiveClosure!transitiveReflexiveClosure lhs "-" Expression rhs
| appendAfter: Expression lhs "\<\<" !>> "=" Expression rhs
| insertBefore: Expression lhs "\>\>" Expression rhs
)
> left modulo: Expression lhs "mod" Expression rhs
> non-assoc ( notIn: Expression lhs "notin" Expression rhs
| \in: Expression lhs "in" Expression rhs
)
> non-assoc ( greaterThanOrEq: Expression lhs "\>=" Expression rhs
| lessThanOrEq : Expression lhs "\<=" Expression rhs
| lessThan : Expression lhs "\<" !>> "-" Expression rhs
| greaterThan : Expression lhs "\>" Expression rhs
)
> non-assoc ( equals : Expression lhs "==" Expression rhs
| nonEquals : Expression lhs "!=" Expression rhs
)
> non-assoc ifDefinedOtherwise: Expression lhs "?" Expression rhs
> non-assoc ( noMatch: Pattern pattern "!:=" Expression expression
| match: Pattern pattern ":=" Expression expression
| enumerator: Pattern pattern "\<-" Expression expression
)
> non-assoc ( implication: Expression lhs "==\>" Expression rhs
| equivalence: Expression lhs "\<==\>" Expression rhs
)
> left and: Expression lhs "&&" Expression rhs
> left or: Expression lhs "||" Expression rhs
> right ifThenElse: Expression condition "?" Expression thenExp ":" Expression elseExp
;
syntax OptionalExpression
= expression: Expression expression
| noExpression: ()
;
syntax UserType
= name: QualifiedName name
| parametric: QualifiedName name >> "[" "[" {Type ","}+ parameters "]" ;
syntax Import
= \extend: "extend" ImportedModule module ";"
| \default: "import" ImportedModule module ";"
| \external: "import" QualifiedName name "=" LocationLiteral at ";"
| \syntax: SyntaxDefinition syntax ;
syntax Body
= toplevels: Toplevel* toplevels ;
lexical URLChars
= ![\t-\n \r \ \< |]* ;
lexical TimeZonePart
= [+ \-] [0-1] [0-9] ":" [0-5] [0-9]
| "Z"
| [+ \-] [0-1] [0-9]
| [+ \-] [0-1] [0-9] [0-5] [0-9]
;
syntax ProtocolPart
= nonInterpolated: ProtocolChars protocolChars
| interpolated: PreProtocolChars pre Expression expression ProtocolTail tail ;
syntax StringTemplate
= ifThen : "if" "(" {Expression ","}+ conditions ")" "{" Statement* preStats StringMiddle body Statement* postStats "}"
| ifThenElse: "if" "(" {Expression ","}+ conditions ")" "{" Statement* preStatsThen StringMiddle thenString Statement* postStatsThen "}" "else" "{" Statement* preStatsElse StringMiddle elseString Statement* postStatsElse "}"
| \for : "for" "(" {Expression ","}+ generators ")" "{" Statement* preStats StringMiddle body Statement* postStats "}"
| doWhile : "do" "{" Statement* preStats StringMiddle body Statement* postStats "}" "while" "(" Expression condition ")"
| \while : "while" "(" Expression condition ")" "{" Statement* preStats StringMiddle body Statement* postStats "}" ;
lexical PreStringChars
= @category="Constant" [\"] StringCharacter* [\<] ;
lexical CaseInsensitiveStringConstant
= @category="Constant" "\'" StringCharacter* chars "\'" ;
lexical Backslash
= [\\] !>> [/ \< \> \\] ;
syntax Label
= \default: Name name ":"
| empty: ;
lexical MidProtocolChars
= "\>" URLChars "\<" ;
lexical NamedBackslash
= [\\] !>> [\< \> \\] ;
syntax Field
= index: IntegerLiteral fieldIndex
| name: Name fieldName ;
lexical JustDate
= "$" DatePart "$";
lexical PostPathChars
= "\>" URLChars "|" ;
syntax PathPart
= nonInterpolated: PathChars pathChars
| interpolated: PrePathChars pre Expression expression PathTail tail ;
lexical DatePart
= [0-9] [0-9] [0-9] [0-9] "-" [0-1] [0-9] "-" [0-3] [0-9]
| [0-9] [0-9] [0-9] [0-9] [0-1] [0-9] [0-3] [0-9] ;
syntax FunctionModifier
= java: "java"
| \test: "test"
| \default: "default";
syntax Assignment
= ifDefined: "?="
| division: "/="
| product: "*="
| intersection: "&="
| subtraction: "-="
| \default: "="
| addition: "+="
| \append: "\<\<="
;
syntax Assignable
= bracket \bracket : "(" Assignable arg ")"
| variable : QualifiedName qualifiedName
| subscript : Assignable receiver "[" Expression subscript "]"
| slice : Assignable receiver "[" OptionalExpression optFirst ".." OptionalExpression optLast "]"
| sliceStep : Assignable receiver "[" OptionalExpression optFirst "," Expression second ".." OptionalExpression optLast "]"
| fieldAccess : Assignable receiver "." Name field
| ifDefinedOrDefault: Assignable receiver "?" Expression defaultExpression
| constructor : Name name "(" {Assignable ","}+ arguments ")"
| \tuple : "\<" {Assignable ","}+ elements "\>"
| annotation : Assignable receiver "@" Name annotation ;
lexical StringConstant
= @category="Constant" "\"" StringCharacter* chars "\"" ;
syntax Assoc
= associative: "assoc"
| left: "left"
| nonAssociative: "non-assoc"
| right: "right" ;
syntax Replacement
= unconditional: Expression replacementExpression
| conditional: Expression replacementExpression "when" {Expression ","}+ conditions ;
syntax DataTarget
= empty:
| labeled: Name label ":" ;
lexical StringCharacter
= "\\" [\" \' \< \> \\ b f n r t]
| UnicodeEscape
| ![\" \' \< \> \\]
| [\n][\ \t \u00A0 \u1680 \u2000-\u200A \u202F \u205F \u3000]* [\'] // margin
;
lexical JustTime
= "$T" TimePartNoTZ !>> [+\-] "$"
| "$T" TimePartNoTZ TimeZonePart "$"
;
lexical MidStringChars
= @category="Constant" [\>] StringCharacter* [\<] ;
lexical ProtocolChars
= [|] URLChars "://" !>> [\t-\n \r \ \u00A0 \u1680 \u2000-\u200A \u202F \u205F \u3000];
lexical RegExpModifier
= [d i m s]* ;
syntax CommonKeywordParameters
= absent: ()
| present: "(" {KeywordFormal ","}+ keywordFormalList ")"
;
syntax Parameters
= \default: "(" Formals formals KeywordFormals keywordFormals ")"
| varArgs: "(" Formals formals "..." KeywordFormals keywordFormals ")" ;
lexical OptionalComma = \default: ","? ;
syntax KeywordFormals
= \default: OptionalComma optionalComma [,\ (\t\n] << {KeywordFormal ","}+ keywordFormalList
| none: ()
;
syntax KeywordFormal
= \default: Type type Name name "=" Expression expression
;
syntax KeywordArguments[&T]
= \default: OptionalComma optionalComma [,\ (\t\n] << {KeywordArgument[&T] ","}+ keywordArgumentList
| none: ()
;
syntax KeywordArgument[&T] = \default: Name name "=" &T expression ;
lexical RegExp
= ![/ \< \> \\]
| "\<" Name "\>"
| [\\] [/ \< \> \\]
| "\<" Name ":" NamedRegExp* "\>"
| Backslash
// | @category="MetaVariable" [\<] Expression expression [\>] TODO: find out why this production existed
;
layout LAYOUTLIST
= LAYOUT* !>> [\u0009-\u000D \u0020 \u0085 \u00A0 \u1680 \u180E \u2000-\u200A \u2028 \u2029 \u202F \u205F \u3000] !>> "//" !>> "/*";
syntax LocalVariableDeclaration
= \default: Declarator declarator
| \dynamic: "dynamic" Declarator declarator ;
lexical RealLiteral
= [0-9]+ [D F d f]
| [0-9]+ [E e] [+ \-]? [0-9]+ [D F d f]?
| [0-9]+ "." !>> "." [0-9]* [D F d f]?
| [0-9]+ "." [0-9]* [E e] [+ \-]? [0-9]+ [D F d f]?
| [.] !<< "." [0-9]+ [D F d f]?
| [.] !<< "." [0-9]+ [E e] [+ \-]? [0-9]+ [D F d f]?
;
syntax Range
= fromTo: Char start "-" Char end
| character: Char character ;
syntax LocationLiteral
= \default: ProtocolPart protocolPart PathPart pathPart ;
syntax ShellCommand
= setOption: "set" QualifiedName name Expression expression
| undeclare: "undeclare" QualifiedName name
| help: "help"
| edit: "edit" QualifiedName name
| unimport: "unimport" QualifiedName name
| listDeclarations: "declarations"
| quit: "quit"
| history: "history"
| \test: "test"
| listModules: "modules"
| clear: "clear";
syntax StringMiddle
= mid: MidStringChars mid
| template: MidStringChars mid StringTemplate template StringMiddle tail
| interpolated: MidStringChars mid Expression expression StringMiddle tail ;
syntax QualifiedName
= \default: {Name "::"}+ names !>> "::" ;
lexical RationalLiteral
= [0-9][0-9]* [r]
| [1-9][0-9]* [r] [0-9][0-9]* !>> [0-9 A-Z _ a-z]
;
lexical DecimalIntegerLiteral
= "0" !>> [0-9 A-Z _ a-z]
| [1-9] [0-9]* !>> [0-9 A-Z _ a-z] ;
syntax DataTypeSelector
= selector: QualifiedName sort "." Name production ;
syntax StringTail
= midInterpolated: MidStringChars mid Expression expression StringTail tail
| post: PostStringChars post
| midTemplate: MidStringChars mid StringTemplate template StringTail tail ;
syntax PatternWithAction
= replacing: Pattern pattern "=\>" Replacement replacement
| arbitrary: Pattern pattern ":" Statement statement ;
lexical LAYOUT
= Comment
// all the white space chars defined in Unicode 6.0
| [\u0009-\u000D \u0020 \u0085 \u00A0 \u1680 \u180E \u2000-\u200A \u2028 \u2029 \u202F \u205F \u3000]
;
syntax Visit
= givenStrategy: Strategy strategy "visit" "(" Expression subject ")" "{" Case+ cases "}"
| defaultStrategy: "visit" "(" Expression subject ")" "{" Case+ cases "}" ;
start syntax Commands
= \commandlist: EvalCommand+ commands
;
start syntax EvalCommand
= declaration: Declaration declaration
| statement: Statement!variableDeclaration!functionDeclaration!visit statement
| \import: Import imported
| output: Output
;
lexical Output
= @category="Result" resultOutput: "⇨" ![\n\r]* [\n]
| @category="StdOut" stdoutOutput: ^ "≫" ![\n\r]* [\n]
| @category="StdErr" stderrOutput: ^ "⚠" ![\n\r]* [\n]
;
start syntax Command
= expression: Expression!nonEmptyBlock expression
| declaration: Declaration declaration
| shell: ":" ShellCommand command
| statement: Statement!variableDeclaration!functionDeclaration!visit statement
| \import: Import imported ;
lexical TagString
= "\\" !<< "{" ( ![{}] | ("\\" [{}]) | TagString)* contents "\\" !<< "}";
syntax ProtocolTail
= mid: MidProtocolChars mid Expression expression ProtocolTail tail
| post: PostProtocolChars post ;
lexical Nonterminal
= ([A-Z] !<< [A-Z] [0-9 A-Z _ a-z]* !>> [0-9 A-Z _ a-z]) \ RascalKeywords;
syntax PathTail
= mid: MidPathChars mid Expression expression PathTail tail
| post: PostPathChars post ;
syntax Visibility
= \private: "private"
| \default:
| \public: "public" ;
syntax StringLiteral
= template: PreStringChars pre StringTemplate template StringTail tail
| interpolated: PreStringChars pre Expression expression StringTail tail
| nonInterpolated: StringConstant constant ;
lexical Comment
= @category="Comment" "/*" (![*] | [*] !>> [/])* "*/"
| @category="Comment" "//" ![\n]* !>> [\ \t\r \u00A0 \u1680 \u2000-\u200A \u202F \u205F \u3000] $ // the restriction helps with parsing speed
;
syntax Renamings
= \default: "renaming" {Renaming ","}+ renamings ;
syntax Tags
= \default: Tag* tags ;
syntax Formals
= \default: {Pattern ","}* formals ;
lexical PostProtocolChars
= "\>" URLChars "://" ;
syntax Start
= absent:
| present: "start" ;
syntax Statement
= @breakable \assert: "assert" Expression expression ";"
| @breakable assertWithMessage: "assert" Expression expression ":" Expression message ";"
| @breakable expression: Expression!visit!nonEmptyBlock expression ";"
| @breakable \visit: Label label Visit visit
| @breakable \while: Label label "while" "(" {Expression ","}+ conditions ")" Statement!variableDeclaration!functionDeclaration body
| @breakable doWhile: Label label "do" Statement body "while" "(" Expression condition ")" ";"
| @breakable @breakable{generators} \for: Label label "for" "(" {Expression ","}+ generators ")" Statement body
| @breakable ifThen: Label label "if" "(" {Expression ","}+ conditions ")" Statement!variableDeclaration!functionDeclaration thenStatement () !>> "else"
| @breakable ifThenElse: Label label "if" "(" {Expression ","}+ conditions ")" Statement thenStatement "else" Statement!variableDeclaration!functionDeclaration elseStatement
| @breakable \switch: Label label "switch" "(" Expression expression ")" "{" Case+ cases "}"
| @breakable \fail: "fail" Target target ";"
| @breakable \break: "break" Target target ";"
| @breakable \continue: "continue" Target target ";"
| @breakable \filter: "filter" ";"
| @breakable \solve: "solve" "(" {QualifiedName ","}+ variables Bound bound ")" Statement!variableDeclaration!functionDeclaration body
| @breakable non-assoc \try: "try" Statement body Catch+ handlers
| @breakable tryFinally: "try" Statement body Catch+ handlers "finally" Statement!variableDeclaration!functionDeclaration finallyBody
| nonEmptyBlock: Label label "{" Statement+ statements "}"
| emptyStatement: ";"
| @breakable globalDirective: "global" Type type {QualifiedName ","}+ names ";"
| @breakable assignment: Assignable assignable Assignment operator Statement!functionDeclaration!variableDeclaration statement
| non-assoc (
@breakable \return : "return" Statement!functionDeclaration!variableDeclaration statement
| @breakable \throw : "throw" Statement!functionDeclaration!variableDeclaration statement
| @breakable \insert : "insert" DataTarget dataTarget Statement!functionDeclaration!variableDeclaration statement
| @breakable \append : "append" DataTarget dataTarget Statement!functionDeclaration!variableDeclaration statement
)
| @breakable functionDeclaration: FunctionDeclaration functionDeclaration
| @breakable variableDeclaration: LocalVariableDeclaration declaration ";"
;
syntax StructuredType
= \default: BasicType basicType "[" {TypeArg ","}+ arguments "]" ;
lexical NonterminalLabel
= [a-z] [0-9 A-Z _ a-z]* !>> [0-9 A-Z _ a-z] ;
syntax FunctionType
= typeArguments: Type type "(" {TypeArg ","}* arguments ")" ;
syntax Case
= @Foldable patternWithAction: "case" PatternWithAction patternWithAction
| @Foldable \default: "default" ":" Statement statement ;
syntax Declarator
= \default: Type type {Variable ","}+ variables ;
syntax Bound
= \default: ";" Expression expression
| empty: ;
keyword RascalKeywords
= "o"
| "syntax"
| "keyword"
| "lexical"
| "int"
| "break"
| "continue"
| "rat"
| "true"
| "bag"
| "num"
| "node"
| "finally"
| "private"
| "real"
| "list"
| "fail"
| "filter"
| "if"
| "tag"
| BasicType
| "extend"
| "append"
| "rel"
| "lrel"
| "void"
| "non-assoc"
| "assoc"
| "test"
| "anno"
| "layout"
| "data"
| "join"
| "it"
| "bracket"
| "in"
| "import"
| "false"
| "all"
| "dynamic"
| "solve"
| "type"
| "try"
| "catch"
| "notin"
| "else"
| "insert"
| "switch"
| "return"
| "case"
| "while"
| "str"
| "throws"
| "visit"
| "tuple"
| "for"
| "assert"
| "loc"
| "default"
| "map"
| "alias"
| "any"
| "module"
| "mod"
| "bool"
| "public"
| "one"
| "throw"
| "set"
| "start"
| "datetime"
| "value"
;
syntax Type
= bracket \bracket: "(" Type type ")"
| user: UserType user
| function: FunctionType function
| structured: StructuredType structured
| basic: BasicType basic
| selector: DataTypeSelector selector
| variable: TypeVar typeVar
| symbol: Sym!nonterminal!labeled!parametrized!parameter symbol
;
syntax Declaration
= variable : Tags tags Visibility visibility Type type {Variable ","}+ variables ";"
| annotation : Tags tags Visibility visibility "anno" Type annoType Type onType "@" Name name ";"
| \alias : Tags tags Visibility visibility "alias" UserType user "=" Type base ";"
| \tag : Tags tags Visibility visibility "tag" Kind kind Name name "on" {Type ","}+ types ";"
| dataAbstract: Tags tags Visibility visibility "data" UserType user CommonKeywordParameters commonKeywordParameters ";"
| @Foldable \data : Tags tags Visibility visibility "data" UserType user CommonKeywordParameters commonKeywordParameters"=" {Variant "|"}+ variants ";"
| function : FunctionDeclaration functionDeclaration
;
syntax Class
= simpleCharclass: "[" Range* ranges "]"
| complement: "!" Class charClass
> left difference: Class lhs "-" Class rhs
> left intersection: Class lhs "&&" Class rhs
> left union: Class lhs "||" Class rhs
| bracket \bracket: "(" Class charclass ")" ;
lexical RegExpLiteral
= "/" RegExp* "/" RegExpModifier ;
syntax FunctionModifiers
= \modifierlist: FunctionModifier* modifiers ;
syntax Comprehension
= @breakable{results,generators} \set: "{" {Expression ","}+ results "|" {Expression ","}+ generators "}"
| @breakable{from,to,generators} \map: "(" Expression from ":" Expression to "|" {Expression ","}+ generators ")"
| @breakable{results,generators} \list: "[" {Expression ","}+ results "|" {Expression ","}+ generators "]" ;
syntax Variant
= nAryConstructor: Name name "(" {TypeArg ","}* arguments KeywordFormals keywordArguments ")" ;
syntax FunctionDeclaration
= abstract: Tags tags Visibility visibility Signature signature ";"
| @Foldable @breakable{expression} expression: Tags tags Visibility visibility Signature signature "=" Expression expression ";"
| @Foldable @breakable{expression,conditions} conditional: Tags tags Visibility visibility Signature signature "=" Expression expression "when" {Expression ","}+ conditions ";"
| @Foldable \default: Tags tags Visibility visibility Signature signature FunctionBody body ;
lexical PreProtocolChars
= "|" URLChars "\<" ;
lexical NamedRegExp
= "\<" Name "\>"
| [\\] [/ \< \> \\]
| NamedBackslash
| ![/ \< \> \\] ;
syntax ProdModifier
= associativity: Assoc associativity
| \bracket: "bracket"
| \tag: Tag tag;
syntax Toplevel
= givenVisibility: Declaration declaration ;
lexical PostStringChars
= @category="Constant" [\>] StringCharacter* [\"] ;
lexical HexIntegerLiteral
= [0] [X x] [0-9 A-F a-f]+ !>> [0-9 A-Z _ a-z] ;
syntax TypeVar
= free: "&" Name name
| bounded: "&" Name name "\<:" Type bound ;
syntax BasicType
= \value: "value"
| \loc: "loc"
| \node: "node"
| \num: "num"
| \type: "type"
| \bag: "bag"
| \int: "int"
| rational: "rat"
| relation: "rel"
| listRelation: "lrel"
| \real: "real"
| \tuple: "tuple"
| string: "str"
| \bool: "bool"
| \void: "void"
| dateTime: "datetime"
| \set: "set"
| \map: "map"
| \list: "list"
;
lexical Char
= @category="Constant" "\\" [\ \" \' \- \< \> \[ \\ \] b f n r t]
| @category="Constant" ![\ \" \' \- \< \> \[ \\ \]]
| @category="Constant" UnicodeEscape
;
syntax Prod
= reference: ":" Name referenced
| labeled: ProdModifier* modifiers Name name ":" Sym* syms
| others: "..."
| unlabeled: ProdModifier* modifiers Sym* syms
| @Foldable associativityGroup: Assoc associativity "(" Prod group ")"
// | TODO add bracket rule for easy readability
> left \all : Prod lhs "|" Prod rhs
> left first : Prod lhs "\>" !>> "\>" Prod rhs
;
syntax DateTimeLiteral
= /*prefer()*/ dateLiteral: JustDate date
| /*prefer()*/ timeLiteral: JustTime time
| /*prefer()*/ dateAndTimeLiteral: DateAndTime dateAndTime ;
lexical PrePathChars
= URLChars "\<" ;
syntax Mapping[&T]
= \default: &T!ifDefinedOtherwise from ":" &T to
;
lexical MidPathChars
= "\>" URLChars "\<" ;
/*
Note that Pattern must closely follow the definitions of Expression because eventually
these two non-terminals will be fused just before AST generation.
*/
syntax Pattern
= \set : "{" {Pattern ","}* elements0 "}"
| \list : "[" {Pattern ","}* elements0 "]"
| qualifiedName : QualifiedName qualifiedName
| multiVariable : QualifiedName qualifiedName "*"
| splice : "*" Pattern argument
| splicePlus : "+" Pattern argument
| negative : "-" Pattern argument
| literal : Literal literal
| \tuple : "\<" {Pattern ","}+ elements "\>"
| typedVariable : Type type Name name
| \map : "(" {Mapping[Pattern] ","}* mappings ")"
| reifiedType : "type" "(" Pattern symbol "," Pattern definitions ")"
| callOrTree : Pattern expression "(" {Pattern ","}* arguments KeywordArguments[Pattern] keywordArguments ")"
> variableBecomes : Name name ":" Pattern pattern
| asType : "[" Type type "]" Pattern argument
| descendant : "/" Pattern pattern
| anti : "!" Pattern pattern
| typedVariableBecomes: Type type Name name ":" Pattern pattern
;
syntax Tag
= @Folded @category="Comment" \default : "@" Name name TagString contents
| @Folded @category="Comment" empty : "@" Name name
| @Folded @category="Comment" expression: "@" Name name "=" Expression expression !>> "@";
syntax ModuleActuals
= \default: "[" {Type ","}+ types "]" ;

View File

@@ -0,0 +1,8 @@
module Syntax
extend lang::std::Layout;
extend lang::std::Id;
start syntax Machine = machine: State+ states;
syntax State = @Foldable state: "state" Id name Trans* out;
syntax Trans = trans: Id event ":" Id to;

483
samples/Reason/JSX.re Normal file
View File

@@ -0,0 +1,483 @@
type component = {displayName: string};
let module Bar = {
let createElement c::c=? children => {
displayName: "test"
};
};
let module Nesting = {
let createElement children => {
displayName: "test"
};
};
let module Much = {
let createElement children => {
displayName: "test"
};
};
let module Foo = {
let createElement a::a=? b::b=? children => {
displayName: "test"
};
};
let module One = {
let createElement
test::test=?
foo::foo=?
children => {
displayName: "test"
};
let createElementobvioustypo
test::test
children => {
displayName: "test"
};
};
let module Two = {
let createElement foo::foo=? children => {
displayName: "test"
};
};
let module Sibling = {
let createElement
foo::foo=?
(children: list component) => {
displayName: "test"
};
};
let module Test = {
let createElement yo::yo=? children => {
displayName: "test"
};
};
let module So = {
let createElement children => {
displayName: "test"
};
};
let module Foo2 = {
let createElement children => {
displayName: "test"
};
};
let module Text = {
let createElement children => {
displayName: "test"
};
};
let module Exp = {
let createElement children => {
displayName: "test"
};
};
let module Pun = {
let createElement intended::intended=? children => {
displayName: "test"
};
};
let module Namespace = {
let module Foo = {
let createElement
intended::intended=?
anotherOptional::x=100
children => {
displayName: "test"
};
};
};
let module LotsOfArguments = {
let createElement
argument1::argument1=?
argument2::argument2=?
argument3::argument3=?
argument4::argument4=?
argument5::argument5=?
argument6::argument6=?
children => {
displayName: "test"
};
};
let div argument1::argument1=? children => {
displayName: "test"
};
let module List1 = {
let createElement children => {
displayName: "test"
};
};
let module List2 = {
let createElement children => {
displayName: "test"
};
};
let module List3 = {
let createElement children => {
displayName: "test"
};
};
let (/><) a b => a + b;
let (><) a b => a + b;
let (/>) a b => a + b;
let (><\/) a b => a + b;
let tag1 = 5 />< 6;
let tag2 = 5 >< 7;
let tag3 = 5 /> 7;
let tag4 = 5 ><\/ 7;
let b = 2;
let selfClosing = <Foo />;
let selfClosing2 = <Foo a=1 b=true />;
let selfClosing3 =
<Foo
a="really long values that should"
b="cause the entire thing to wrap"
/>;
let a = <Foo> <Bar c=(fun a => a + 2) /> </Foo>;
let a3 = <So> <Much> <Nesting /> </Much> </So>;
let a4 =
<Sibling>
<One test=true foo=b />
<Two foo=b />
</Sibling>;
let a5 = <Foo> "testing a string here" </Foo>;
let a6 =
<Foo2>
<Text> "testing a string here" </Text>
<Test yo=1 />
<Text> "another string" </Text>
<Bar />
<Exp> (2 + 4) </Exp>
</Foo2>;
let intended = true;
let punning = <Pun intended />;
let namespace = <Namespace.Foo />;
let c = <Foo />;
let d = <Foo />;
let spaceBefore =
<So> <Much> <Nesting /> </Much> </So>;
let spaceBefore2 = <So> <Much /> </So>;
let siblingNotSpaced =
<So> <Much /> <Much /> </So>;
let jsxInList = [<Foo />];
let jsxInList2 = [<Foo />];
let jsxInListA = [<Foo />];
let jsxInListB = [<Foo />];
let jsxInListC = [<Foo />];
let jsxInListD = [<Foo />];
let jsxInList3 = [<Foo />, <Foo />, <Foo />];
let jsxInList4 = [<Foo />, <Foo />, <Foo />];
let jsxInList5 = [<Foo />, <Foo />];
let jsxInList6 = [<Foo />, <Foo />];
let jsxInList7 = [<Foo />, <Foo />];
let jsxInList8 = [<Foo />, <Foo />];
let testFunc b => b;
let jsxInFnCall = testFunc <Foo />;
let lotsOfArguments =
<LotsOfArguments
argument1=1
argument2=2
argument3=3
argument4=4
argument5=5
argument6="test">
<Namespace.Foo />
</LotsOfArguments>;
let lowerCase = <div argument1=1 />;
let b = 0;
let d = 0;
/*
* Should pun the first example:
*/
let a = <Foo a> 5 </Foo>;
let a = <Foo a=b> 5 </Foo>;
let a = <Foo a=b b=d> 5 </Foo>;
let a = <Foo a> 0.55 </Foo>;
let a = Foo.createElement "" [@JSX];
let ident = <Foo> a </Foo>;
let fragment1 = <> <Foo /> <Foo /> </>;
let fragment2 = <> <Foo /> <Foo /> </>;
let fragment3 = <> <Foo /> <Foo /> </>;
let fragment4 = <> <Foo /> <Foo /> </>;
let fragment5 = <> <Foo /> <Foo /> </>;
let fragment6 = <> <Foo /> <Foo /> </>;
let fragment7 = <> <Foo /> <Foo /> </>;
let fragment8 = <> <Foo /> <Foo /> </>;
let fragment9 = <> 2 2 2 2 </>;
let fragment10 = <> 2.2 3.2 4.6 1.2 </>;
let fragment11 = <> "str" </>;
let fragment12 = <> (6 + 2) (6 + 2) (6 + 2) </>;
let fragment13 = <> fragment11 fragment11 </>;
let listOfItems1 = <List1> 1 2 3 4 5 </List1>;
let listOfItems2 =
<List2> 1.0 2.8 3.8 4.0 5.1 </List2>;
let listOfItems3 =
<List3> fragment11 fragment11 </List3>;
/*
* Several sequential simple jsx expressions must be separated with a space.
*/
let thisIsRight a b => ();
let tagOne children => ();
let tagTwo children => ();
/* thisIsWrong <tagOne /><tagTwo />; */
thisIsRight <tagOne /> <tagTwo />;
/* thisIsWrong <tagOne> </tagOne><tagTwo> </tagTwo>; */
thisIsRight <tagOne /> <tagTwo />;
let a children => ();
let b children => ();
let thisIsOkay =
<List1> <a /> <b /> <a /> <b /> </List1>;
let thisIsAlsoOkay =
<List1> <a /> <b /> </List1>;
/* Doesn't make any sense, but suppose you defined an
infix operator to compare jsx */
<a /> < <b />;
<a /> > <b />;
<a /> < <b />;
<a /> > <b />;
let listOfListOfJsx = [<> </>];
let listOfListOfJsx = [<> <Foo /> </>];
let listOfListOfJsx = [
<> <Foo /> </>,
<> <Bar /> </>
];
let listOfListOfJsx = [
<> <Foo /> </>,
<> <Bar /> </>,
...listOfListOfJsx
];
let sameButWithSpaces = [<> </>];
let sameButWithSpaces = [<> <Foo /> </>];
let sameButWithSpaces = [
<> <Foo /> </>,
<> <Bar /> </>
];
let sameButWithSpaces = [
<> <Foo /> </>,
<> <Bar /> </>,
...sameButWithSpaces
];
/*
* Test named tag right next to an open bracket.
*/
let listOfJsx = [];
let listOfJsx = [<Foo />];
let listOfJsx = [<Foo />, <Bar />];
let listOfJsx = [<Foo />, <Bar />, ...listOfJsx];
let sameButWithSpaces = [];
let sameButWithSpaces = [<Foo />];
let sameButWithSpaces = [<Foo />, <Bar />];
let sameButWithSpaces = [
<Foo />,
<Bar />,
...sameButWithSpaces
];
/**
* Test no conflict with polymorphic variant types.
*/
type thisType = [ | `Foo | `Bar];
type t 'a = [< thisType] as 'a;
let asd =
<One test=true foo=2> "a" "b" </One> [@foo];
let asd2 =
One.createElementobvioustypo
test::false
["a", "b"]
[@JSX]
[@foo];
let span
test::(test: bool)
foo::(foo: int)
children => 1;
let asd =
<span test=true foo=2> "a" "b" </span> [@foo];
/* "video" call doesn't end with a list, so the expression isn't converted to JSX */
let video test::(test: bool) children => children;
let asd2 = video test::false 10 [@JSX] [@foo];
let div children => 1;
((fun () => div) ()) [] [@JSX];
let myFun () =>
<>
<Namespace.Foo
intended=true
anotherOptional=200
/>
<Namespace.Foo
intended=true
anotherOptional=200
/>
<Namespace.Foo
intended=true anotherOptional=200>
<Foo />
<Foo />
<Foo />
<Foo />
<Foo />
<Foo />
<Foo />
</Namespace.Foo>
</>;
let myFun () => <> </>;
let myFun () =>
<>
<Namespace.Foo
intended=true
anotherOptional=200
/>
<Namespace.Foo
intended=true
anotherOptional=200
/>
<Namespace.Foo
intended=true anotherOptional=200>
<Foo />
<Foo />
<Foo />
<Foo />
<Foo />
<Foo />
<Foo />
</Namespace.Foo>
</>;
/**
* Children should wrap without forcing attributes to.
*/
<Foo a=10 b=0>
<Bar />
<Bar />
<Bar />
<Bar />
</Foo>;
/**
* Failing test cases:
*/
/* let res = <Foo a=10 b=(<Foo a=200 />) > */
/* <Bar /> */
/* </Foo>; */
/* let res = <Foo a=10 b=(<Foo a=200 />) />; */

1326
samples/Reason/Layout.re Normal file

File diff suppressed because it is too large Load Diff

344
samples/Reason/Machine.re Normal file
View File

@@ -0,0 +1,344 @@
open Format;
let module Endo = {
type t 'a = 'a => 'a;
};
let module Syntax = {
let module Var = {
type t = int;
};
let module Term = {
type t =
| App t t
| Lam t
| Var Var.t
;
};
let module Sub = {
type t 'a =
| Cmp (t 'a) (t 'a)
| Dot 'a (t 'a)
| Id
| Shift
;
let map f sgm => {
let rec go = fun
| Cmp sgm0 sgm1 => Cmp (go sgm0) (go sgm1)
| Dot a sgm => Dot (f a) (go sgm)
| Id => Id
| Shift => Shift
;
go sgm;
};
let rec apply sgm e =>
switch (sgm, e) {
| (sgm, Term.App e0 e1) => Term.App (apply sgm e0) (apply sgm e1)
| (sgm, Term.Lam e) => Term.Lam (apply (Dot (Term.Var 0) (Cmp sgm Shift)) e)
| (Dot e _, Term.Var 0) => e
| (Dot _ sgm, Term.Var i) => apply sgm (Term.Var (i - 1))
| (Id, Term.Var i) => Term.Var i
| (Shift, Term.Var i) => Term.Var (i + 1)
| (Cmp rho sgm, e) => apply sgm (apply rho e)
};
};
};
let module Zip = {
open Syntax;
type t 'a =
| App0 (t 'a) 'a
| App1 'a (t 'a)
| Halt
| Lam (t 'a)
;
let map f sgm => {
let rec go = fun
| App0 zip e1 => App0 (go zip) (f e1)
| App1 e0 zip => App1 (f e0) (go zip)
| Halt => Halt
| Lam zip => Lam (go zip)
;
go sgm;
};
let rec apply zip acc => switch zip {
| App0 zip e1 => apply zip (Term.App acc e1)
| App1 e0 zip => apply zip (Term.App e0 acc)
| Halt => acc
| Lam zip => apply zip (Term.Lam acc)
};
};
let module Clo = {
open Syntax;
type t =
| Clo Term.t (Sub.t t);
let rec from (Clo term sgm) => Sub.apply (Sub.map from sgm) term;
};
let module Pretty = {
let module Delim = {
type t = string;
let pp prev next fmt token => if (prev < next) { fprintf fmt "%s" token };
};
let module Prec = {
type t = int;
open Syntax.Term;
let calc = fun
| App _ _ => 1
| Lam _ => 2
| Var _ => 0
;
};
let module Name = {
type t = string;
let suffix = {
let script = fun
| 0 => ""
| 1 => ""
| 2 => ""
| 3 => ""
| 4 => ""
| 5 => ""
| 6 => ""
| 7 => ""
| 8 => ""
| 9 => ""
| _ => failwith "bad subscript";
let rec go acc => fun
| 0 => acc
| n => go (script (n mod 10) ^ acc) (n / 10);
go ""
};
let gen = {
let offset = 97;
let width = 26;
fun () i => {
let code = i mod width + offset;
let char = Char.chr code;
let prime = i / width;
let suffix = suffix prime;
let name = Char.escaped char ^ suffix;
Some name;
}
};
};
let module Env = {
type t = {
used: list Name.t,
rest: Stream.t Name.t,
};
let mk () => {
let used = [];
let rest = Stream.from @@ Name.gen ();
{ used, rest };
};
};
type printer 'a = Env.t => Prec.t => formatter => 'a => unit;
let module Term = {
open Syntax.Term;
let rec pp ({ Env.used: used, rest } as env) prev fmt e => {
let next = Prec.calc e;
switch e {
| App e0 e1 =>
fprintf fmt "@[%a%a@ %a%a@]"
(Delim.pp prev next) "("
(pp env 1) e0
(pp env 0) e1
(Delim.pp prev next) ")"
| Lam e =>
let name = Stream.next rest;
let env = { ...env, Env.used: [name, ...used] };
fprintf fmt "%aλ%a.%a%a"
(Delim.pp prev next) "("
(pp_print_string) name
(pp env next) e
(Delim.pp prev next) ")"
| Var index =>
fprintf fmt "%s" @@ try (List.nth used index) {
| _ => "#" ^ string_of_int index
}
}
};
};
let module Sub = {
open Syntax.Sub;
let rec pp pp_elem env prev fmt => fun
| Cmp sgm1 sgm0 =>
fprintf fmt "@[%a;@ %a@]"
(pp pp_elem env prev) sgm1
(pp pp_elem env prev) sgm0
| Dot e sgm =>
fprintf fmt "@[%a@ ·@ %a@]"
(pp_elem env prev) e
(pp pp_elem env prev) sgm
| Id =>
fprintf fmt "ι"
| Shift =>
fprintf fmt ""
;
};
let module Clo = {
let rec pp env prev fmt (Clo.Clo e sgm) => {
let next = Prec.calc e;
fprintf fmt "@[%a%a%a[%a]@]"
(Delim.pp prev next) "("
(Term.pp env next) e
(Delim.pp prev next) ")"
(Sub.pp pp env next) sgm
};
};
let module Zip = {
open Zip;
let rec pp pp_elem env prev fmt => fun
| App0 zip elem =>
fprintf fmt "inl@[<v -1>⟨@,%a@,%a⟩@]"
(pp pp_elem env prev) zip
(pp_elem env prev) elem
| App1 elem zip =>
fprintf fmt "inr@[<v -1>⟨@,%a@,%a⟩@]"
(pp_elem env prev) elem
(pp pp_elem env prev) zip
| Halt =>
fprintf fmt "halt"
| Lam zip =>
fprintf fmt "lam@[<v -1>⟨@,%a⟩@]"
(pp pp_elem env prev) zip
;
};
};
let module Machine = {
type t = {
clo: Clo.t,
ctx: Zip.t Clo.t,
};
let into e => {
open Clo;
open Syntax.Sub;
let clo = Clo e Id;
let ctx = Zip.Halt;
{ clo, ctx }
};
let from { clo, ctx } => Zip.apply (Zip.map Clo.from ctx) (Clo.from clo);
let pp fmt rule state => {
fprintf fmt "@[<v>ctx ::@[<v -5>@,%a@]@,clo ::@[<v -5>@,%a@]@,rule ::@[<v -5>@,%a@]@,term ::@[<v -5>@,%a@]@]@."
(Pretty.Zip.pp Pretty.Clo.pp (Pretty.Env.mk ()) 2) state.ctx
(Pretty.Clo.pp (Pretty.Env.mk ()) 2) state.clo
(pp_print_string) rule
(Pretty.Term.pp (Pretty.Env.mk ()) 2) (from state)
};
let halted state => {
open Clo;
open Syntax.Sub;
open Syntax.Term;
switch state {
| { clo: Clo (Var _) Id, _ } => true
| _ => false
} [@warning "-4"];
};
let step state => {
open Clo;
open Syntax.Sub;
open Syntax.Term;
let rule = ref "";
let state = switch state {
/* left */
| { clo: Clo (App e0 e1) sgm, ctx } =>
let clo = Clo e0 sgm;
let ctx = Zip.App0 ctx (Clo e1 sgm);
rule := "LEFT";
{ clo, ctx };
/* beta */
| { clo: Clo (Lam e) sgm, ctx: Zip.App0 ctx c0 } =>
let clo = Clo e (Cmp (Dot c0 sgm) Id);
rule := "BETA";
{ clo, ctx };
/* lambda */
| { clo: Clo (Lam e) sgm, ctx } =>
let clo = Clo e (Cmp (Dot (Clo (Var 0) Id) (Cmp sgm Shift)) Id);
let ctx = Zip.Lam ctx;
rule := "LAMBDA";
{ clo, ctx };
/* associate */
| { clo: Clo (Var n) (Cmp (Cmp pi rho) sgm), ctx } =>
let clo = Clo (Var n) (Cmp pi (Cmp rho sgm));
rule := "ASSOCIATE";
{ clo, ctx };
/* head */
| { clo: Clo (Var 0) (Cmp (Dot (Clo e pi) _) sgm), ctx } =>
let clo = Clo e (Cmp pi sgm);
rule := "HEAD";
{ clo, ctx };
/* tail */
| { clo: Clo (Var n) (Cmp (Dot (Clo _ _) rho) sgm), ctx } =>
let clo = Clo (Var (n - 1)) (Cmp rho sgm);
rule := "TAIL";
{ clo, ctx };
/* shift */
| { clo: Clo (Var n) (Cmp Shift sgm), ctx } =>
let clo = Clo (Var (n + 1)) sgm;
rule := "SHIFT";
{ clo, ctx };
/* id */
| { clo: Clo (Var n) (Cmp Id sgm), ctx } =>
let clo = Clo (Var n) sgm;
rule := "ID";
{ clo, ctx };
| _ =>
pp std_formatter !rule state;
failwith "bad state";
} [@warning "-4"];
pp std_formatter !rule state;
state;
};
let norm e => {
let count = ref 0;
let state = ref (into e);
while (not (halted !state)) {
fprintf std_formatter "@\n--- step[%d] ---@\n" !count;
incr count;
state := step !state;
};
from !state;
};
};
let module Test = {
open Syntax.Term;
let l e => Lam e;
let ( *@ ) e0 e1 => App e0 e1;
let ff = l (l (Var 1));
let tt = l (l (Var 0));
let zero = l (l (Var 1));
let succ = l (l (l (Var 0 *@ Var 2)));
let one = succ *@ zero;
let two = succ *@ one;
let three = succ *@ two;
let const = l (l (Var 1));
let fix = l (l (Var 1 *@ (Var 0 *@ Var 0)) *@ l (Var 1 *@ (Var 0 *@ Var 0)));
let add = fix *@ l (l (l (Var 1 *@ Var 0 *@ l (succ *@ Var 3 *@ Var 0 *@ Var 1))));
let init = l (l (Var 0) *@ l (l (Var 1)));
};
let module Run = {
let go () => Machine.norm Test.init;
};

View File

@@ -0,0 +1,308 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
*/
let startedMerlin: ref (option Js.Unsafe.any) = {contents: None};
let fixedEnv = Js.Unsafe.js_expr "require('../lib/fixedEnv')";
/* This and the subsequent big js blocks are copied over from Nuclide. More convenient for now. */
let findNearestMerlinFile' = Js.Unsafe.js_expr {|
function findNearestMerlinFile(beginAtFilePath) {
var path = require('path');
var fs = require('fs');
var fileDir = path.dirname(beginAtFilePath);
var currentPath = path.resolve(fileDir);
do {
var fileToFind = path.join(currentPath, '.merlin');
var hasFile = fs.existsSync(fileToFind);
if (hasFile) {
return path.dirname(currentPath);
}
if (path.dirname(currentPath) === currentPath) {
// Bail
return '.';
}
currentPath = path.dirname(currentPath);
} while (true);
}
|};
let findNearestMerlinFile beginAtFilePath::path => {
let result = Js.Unsafe.fun_call findNearestMerlinFile' [|Js.Unsafe.inject (Js.string path)|];
Js.to_string result
};
let createMerlinReaderFnOnce' = Js.Unsafe.js_expr {|
function(ocamlMerlinPath, ocamlMerlinFlags, dotMerlinDir, fixedEnv) {
var spawn = require('child_process').spawn;
// To split while stripping out any leading/trailing space, we match on all
// *non*-whitespace.
var items = ocamlMerlinFlags === '' ? [] : ocamlMerlinFlags.split(/\s+/);
var merlinProcess = spawn(ocamlMerlinPath, items, {cwd: dotMerlinDir});
merlinProcess.stderr.on('data', function(d) {
console.error('Ocamlmerlin: something wrong happened:');
console.error(d.toString());
});
merlinProcess.stdout.on('close', function(d) {
console.error('Ocamlmerlin: closed.');
});
var cmdQueue = [];
var hasStartedReading = false;
var readline = require('readline');
var reader = readline.createInterface({
input: merlinProcess.stdout,
terminal: false,
});
return function(cmd, resolve, reject) {
cmdQueue.push([resolve, reject]);
if (!hasStartedReading) {
hasStartedReading = true;
reader.on('line', function(line) {
var response;
try {
response = JSON.parse(line);
} catch (err) {
response = null;
}
var resolveReject = cmdQueue.shift();
var resolve = resolveReject[0];
var reject = resolveReject[1];
if (!response || !Array.isArray(response) || response.length !== 2) {
reject(new Error('Unexpected ocamlmerlin output format: ' + line));
return;
}
var status = response[0];
var content = response[1];
var errorResponses = {
'failure': true,
'error': true,
'exception': true,
};
if (errorResponses[status]) {
reject(new Error('Ocamlmerlin returned an error: ' + line));
return;
}
resolve(content);
});
}
merlinProcess.stdin.write(JSON.stringify(cmd));
};
}
|};
let createMerlinReaderFnOnce
pathToMerlin::pathToMerlin
merlinFlags::merlinFlags
dotMerlinPath::dotMerlinPath =>
Js.Unsafe.fun_call
createMerlinReaderFnOnce'
[|
Js.Unsafe.inject (Js.string pathToMerlin),
Js.Unsafe.inject (Js.string merlinFlags),
Js.Unsafe.inject (Js.string dotMerlinPath),
Js.Unsafe.inject fixedEnv
|];
let startMerlinProcess path::path =>
switch startedMerlin.contents {
| Some readerFn => ()
| None =>
let atomReasonPathToMerlin = Atom.Config.get "atom-reason.pathToMerlin";
let atomReasonMerlinFlags = Atom.Config.get "atom-reason.merlinFlags";
let atomReasonMerlinLogFile = Atom.Config.get "atom-reason.merlinLogFile";
switch atomReasonMerlinLogFile {
| JsonString "" => ()
| JsonString s => Atom.Env.setEnvVar "MERLIN_LOG" s
| _ => ()
};
let readerFn =
createMerlinReaderFnOnce
pathToMerlin::(Atom.JsonValue.unsafeExtractString atomReasonPathToMerlin)
merlinFlags::(Atom.JsonValue.unsafeExtractString atomReasonMerlinFlags)
dotMerlinPath::(findNearestMerlinFile beginAtFilePath::path);
startedMerlin.contents = Some readerFn
};
let readOneLine cmd::cmd resolve reject =>
switch startedMerlin.contents {
| None => raise Not_found
| Some readerFn =>
Js.Unsafe.fun_call
readerFn
[|
Js.Unsafe.inject cmd,
Js.Unsafe.inject (Js.wrap_callback resolve),
Js.Unsafe.inject (Js.wrap_callback reject)
|]
};
/* contextify is important for avoiding different buffers calling the backing merlin at the same time. */
/* https://github.com/the-lambda-church/merlin/blob/d98a08d318ca14d9c702bbd6eeadbb762d325ce7/doc/dev/PROTOCOL.md#contextual-commands */
let contextify query::query path::path => Js.Unsafe.obj [|
("query", Js.Unsafe.inject query),
("context", Js.Unsafe.inject (Js.array [|Js.string "auto", Js.string path|]))
|];
let prepareCommand text::text path::path query::query resolve reject => {
startMerlinProcess path;
/* These two commands should be run before every main command. */
readOneLine
cmd::(
contextify
/* The protocol command tells Merlin which API version we want to use. (2 for us) */
query::(
Js.array [|
Js.Unsafe.inject (Js.string "protocol"),
Js.Unsafe.inject (Js.string "version"),
Js.Unsafe.inject (Js.number_of_float 2.)
|]
)
path::path
)
(
fun _ =>
readOneLine
cmd::(
contextify
/* The tell command allows us to synchronize our text with Merlin's internal buffer. */
query::(
Js.array [|Js.string "tell", Js.string "start", Js.string "end", Js.string text|]
)
path::path
)
(fun _ => readOneLine cmd::(contextify query::query path::path) resolve reject)
reject
)
reject
};
let positionToJsMerlinPosition (line, col) => Js.Unsafe.obj [|
/* lines (rows) are 1-based for merlin, not 0-based, like for Atom */
("line", Js.Unsafe.inject (Js.number_of_float (float_of_int (line + 1)))),
("col", Js.Unsafe.inject (Js.number_of_float (float_of_int col)))
|];
/* Actual merlin commands we'll use. */
let getTypeHint path::path text::text position::position resolve reject =>
prepareCommand
text::text
path::path
query::(
Js.array [|
Js.Unsafe.inject (Js.string "type"),
Js.Unsafe.inject (Js.string "enclosing"),
Js.Unsafe.inject (Js.string "at"),
Js.Unsafe.inject (positionToJsMerlinPosition position)
|]
)
resolve
reject;
let getAutoCompleteSuggestions
path::path
text::text
position::position
prefix::prefix
resolve
reject =>
prepareCommand
text::text
path::path
query::(
Js.array [|
Js.Unsafe.inject (Js.string "complete"),
Js.Unsafe.inject (Js.string "prefix"),
Js.Unsafe.inject (Js.string prefix),
Js.Unsafe.inject (Js.string "at"),
Js.Unsafe.inject (positionToJsMerlinPosition position),
Js.Unsafe.inject (Js.string "with"),
Js.Unsafe.inject (Js.string "doc")
|]
)
resolve
reject;
let getDiagnostics path::path text::text resolve reject =>
prepareCommand
text::text
path::path
query::(Js.array [|Js.Unsafe.inject (Js.string "errors")|])
resolve
reject;
let locate path::path text::text extension::extension position::position resolve reject =>
prepareCommand
text::text
path::path
query::(
Js.array [|
Js.Unsafe.inject (Js.string "locate"),
Js.Unsafe.inject (Js.string ""),
Js.Unsafe.inject (Js.string extension),
Js.Unsafe.inject (Js.string "at"),
Js.Unsafe.inject (positionToJsMerlinPosition position)
|]
)
resolve
reject;
/* reject */
let getOccurrences path::path text::text position::position resolve reject =>
prepareCommand
text::text
path::path
query::(
Js.array [|
Js.Unsafe.inject (Js.string "occurrences"),
Js.Unsafe.inject (Js.string "ident"),
Js.Unsafe.inject (Js.string "at"),
Js.Unsafe.inject (positionToJsMerlinPosition position)
|]
)
resolve
reject;
let destruct
path::path
text::text
startPosition::startPosition
endPosition::endPosition
resolve
reject =>
prepareCommand
text::text
path::path
query::(
Js.array [|
Js.Unsafe.inject (Js.string "case"),
Js.Unsafe.inject (Js.string "analysis"),
Js.Unsafe.inject (Js.string "from"),
Js.Unsafe.inject (positionToJsMerlinPosition startPosition),
Js.Unsafe.inject (Js.string "to"),
Js.Unsafe.inject (positionToJsMerlinPosition endPosition)
|]
)
resolve
reject;
let getOutline path::path text::text resolve reject =>
prepareCommand
text::text
path::path
query::(Js.array [|Js.Unsafe.inject (Js.string "outline")|])
resolve
reject;

989
samples/Reason/Syntax.re Normal file
View File

@@ -0,0 +1,989 @@
/* Copyright (c) 2015-present, Facebook, Inc. All rights reserved. */
[@@@autoFormat let wrap = 80; let shift = 2];
Modules.run ();
Polymorphism.run ();
Variants.run ();
BasicStructures.run ();
TestUtils.printSection "General Syntax";
/* Won't work! */
/* let matchingFunc a = match a with */
/* `Thingy x => (print_string "matched thingy x"); x */
/* | `Other x => (print_string "matched other x"); x;; */
/* */
let matchingFunc a =>
switch a {
| `Thingy x =>
print_string "matched thingy x";
let zz = 10;
zz
| `Other x =>
print_string "matched other x";
x
};
type firstTwoShouldBeGroupedInParens =
(int => int) => int => int;
type allParensCanBeRemoved =
int => int => int => int;
type firstTwoShouldBeGroupedAndFirstThree =
((int => int) => int) => int;
/* Same thing now but with type constructors instead of each int */
type firstTwoShouldBeGroupedInParens =
(list int => list int) => list int => list int;
type allParensCanBeRemoved =
list int => list int => list int => list int;
type firstTwoShouldBeGroupedAndFirstThree =
((list int => list int) => list int) =>
list int;
type myRecordType = {
firstTwoShouldBeGroupedInParens:
(int => int) => int => int,
allParensCanBeRemoved:
int => int => int => int,
firstTwoShouldBeGroupedAndFirstThree:
((int => int) => int) => int
};
type firstNamedArgShouldBeGroupedInParens =
first::(int => int) => second::int => int;
type allParensCanBeRemoved =
first::int => second::int => third::int => int;
type firstTwoShouldBeGroupedAndFirstThree =
first::((int => int) => int) => int;
/* Same thing now, but with type constructors instead of int */
type firstNamedArgShouldBeGroupedInParens =
first::(list int => list int) =>
second::list int =>
list int;
type allParensCanBeRemoved =
first::list int =>
second::list int =>
third::list int =>
list int;
type firstTwoShouldBeGroupedAndFirstThree =
first::((list int => list int) => list int) =>
list int;
type firstNamedArgShouldBeGroupedInParens =
first::(int => int)? =>
second::int list? =>
int;
/* The arrow necessitates parens around the next two args. The ? isn't what
* makes the parens necessary. */
type firstNamedArgShouldBeGroupedInParensAndSecondNamedArg =
first::(int => int)? =>
second::(int => int)? =>
int;
type allParensCanBeRemoved =
first::int? =>
second::int? =>
third::int? =>
int;
type firstTwoShouldBeGroupedAndFirstThree =
first::((int => int) => int) => int;
type noParens =
one::int => int => int => two::int => int;
type noParensNeeded =
one::int => int => int => two::int => int;
type firstNamedArgNeedsParens =
one::(int => int => int) => two::int => int;
/* Now, let's try type aliasing */
/* Unless wrapped in parens, types between arrows may not be aliased, may not
* themselves be arrows. */
type parensRequiredAroundFirstArg =
(list int as 'a) => int as 'a;
type parensRequiredAroundReturnType =
(list int as 'a) => (int as 'a);
type parensRequiredAroundReturnType =
(list int as 'a) => (int as 'a) as 'b;
type noParensNeededWhenInTuple =
(list int as 'a, list int as 'b) as 'entireThing;
type myTypeDef 'a = list 'a;
type instatiatedTypeDef = myTypeDef int => int;
/* Test a type attribute for good measure */
/* We should clean up all of the attribute tagging eventually, but for now,
* let's make it super ugly to get out of the way of all the formatting/parsing
* implementations (fewer conflicts during parsing, fewer edge cases during
* printing).
*/
type something = (
int,
int [@lookAtThisAttribute]
);
type longWrappingTypeDefinitionExample =
M_RK__G.Types.instance
(TGRecognizer.tGFields unit unit)
(TGRecognizer.tGMethods unit unit);
type semiLongWrappingTypeDefinitionExample =
M_RK__Gesture.Types.instance
TGRecognizerFinal.tGFields
TGRecognizerFinal.tGMethods;
type semiLongWrappingTypeWithConstraint =
M_RK__Gesture.Types.instance
'a
TGRecognizerFinal.tGFields
TGRecognizerFinal.tGMethods
constraint 'a = (unit, unit);
type onelineConstrain = 'a constraint 'a = int;
/* This must be in trunk but not in this branch of OCaml */
/* type withNestedRecords = MyConstructor {myField: int} */
type colors =
| Red int
| Black int
| Green int;
/* Another approach is to require declared variants to wrap any record */
/* type myRecord = MyRecord {name: int}; */
/* let myValue = MyRecord {name: int}; */
/* This would force importing of the module */
/* This would also lend itself naturally to pattern matching - and avoid having
to use `.` operator at all since you normally destructure. */
type nameBlahType = {nameBlah: int};
let myRecord = {nameBlah: 20};
let myRecordName = myRecord.nameBlah;
let {nameBlah}: nameBlahType = {nameBlah: 20};
print_int nameBlah;
let {nameBlah: aliasedToThisVar}: nameBlahType = {
nameBlah: 20
};
print_int aliasedToThisVar;
let desiredFormattingForWrappedLambda:
int => int => int => nameBlahType =
/*
fun is
pre- /firstarg\
fix /-coupled--\
|-\ /-to-prefix--\ */
fun curriedArg anotherArg lastArg => {
nameBlah: 10
};
type longerInt = int;
let desiredFormattingForWrappedLambdaWrappedArrow:
longerInt =>
longerInt =>
longerInt =>
nameBlahType =
/*
fun is
pre- /firstarg\
fix /-coupled--\
|-\ /-to-prefix--\ */
fun curriedArg anotherArg lastArg => {
nameBlah: 10
};
let desiredFormattingForWrappedLambdaReturnOnNewLine
/*
fun is
pre- /firstarg\
fix /-coupled--\
|-\ /-to-prefix--\ */
curriedArg
anotherArg
lastArg => {
nameBlah: 10
};
/*
let is
pre-
fix /-function binding name---\
|-\ / is coupled to prefix \ */
let desiredFormattingForWrappedSugar
curriedArg
anotherArg
lastArg => {
nameBlah: 10
};
/*
let is
pre-
fix /-function binding name---\
|-\ / is coupled to prefix \ */
let desiredFormattingForWrappedSugarReturnOnNewLine
curriedArg
anotherArg
lastArg => {
nameBlah: 10
};
/*
let : type t1 t2. t1 * t2 list -> t1 = ...
let rec f : 't1 't2. 't1 * 't2 list -> 't1 =
fun (type t1) (type t2) -> (... : t1 * t2 list -> t1)
*/
type point = {x: int, y: int};
type point3D = {x: int, y: int, z: int};
let point2D = {x: 20, y: 30};
let point3D: point3D = {
x: 10,
y: 11,
z: 80 /* Optional Comma */
};
let printPoint (p: point) => {
print_int p.x;
print_int p.y
};
let addPoints (p1: point, p2: point) => {
x: p1.x + p2.x,
y: p1.y + p2.y
};
let res1 = printPoint point2D;
let res2 =
printPoint {x: point3D.x, y: point3D.y};
/*
When () were used to indicate sequences, the parser used seq_expr not only
for grouping sequences, but also to form standard precedences.
/------- sequence_expr ------\
let res3 = printPoint (addPoints (point2D, point3D));
Interestingly, it knew that tuples aren't sequences.
To move towards semi delimited, semi-terminated, braces-grouped sequences:
while allowing any non-sequence expression to be grouped on parens, we make
an explicit rule that allows one single non-semi ended expression to be
grouped in parens.
Actually: We will allow an arbitrary number of semi-delimited expressions to
be wrapped in parens, but the braces grouped semi delimited (sequence)
expressions must *also* be terminated with a semicolon.
This allows the parser to distinguish between
let x = {a}; /* Record {a:a} */
let x = {a;}; /* Single item sequence returning identifier {a} */
*/
let res3 =
printPoint (
addPoints (
point2D,
{x: point3D.x, y: point3D.y}
)
);
type person = {age: int, name: string};
type hiredPerson = {
age: string,
name: string,
dateHired: int
};
let o: person = {name: "bob", age: 10};
/* Parens needed? Nope! */
let o: person = {name: "bob", age: 10};
let printPerson (p: person) => {
let q: person = p;
p.name ^ p.name
};
/* let dontParseMeBro x y:int = x = y;*/
/* With this unification, anywhere eyou see `= fun` you can just ommit it */
let blah a => a; /* Done */
let blah a => a; /* Done (almost) */
let blah a b => a; /* Done */
let blah a b => a; /* Done (almost) */
/* More than one consecutive pattern must have a single case */
type blah = {blahBlah: int};
let blah a {blahBlah} => a;
let blah a {blahBlah} => a;
let module TryToExportTwice = {
let myVal = "hello";
};
/*
Unifying top level module syntax with local module syntax is probably a bad
idea at the moment because it makes it more difficult to continue to support
`let .. in` bindings. We can distinguish local modules for `let..in` that
just happen to be defined at the top level (but not exported).
let MyModule = {let myVal = 20;} in
MyModule.x
Wait, where would this ever be valid, even if we continued to support
`let..in`?
*/
let onlyDoingThisTopLevelLetToBypassTopLevelSequence = {
let x = {
print_int 1;
print_int 20 /* Missing trailing SEMI */
};
let x = {
print_int 1;
print_int 20; /* Ensure missing middle SEMI reported well */
print_int 20
};
let x = {
print_int 1;
print_int 20;
10
/* Comment in final position */
}; /* Missing final SEMI */
x + x
};
type hasA = {a: int};
let a = 10;
let returnsASequenceExpressionWithASingleIdentifier
() => a;
let thisReturnsA () => a;
let thisReturnsAAsWell () => a;
let recordVal: int = (thisReturnsARecord ()).a;
Printf.printf
"\nproof that thisReturnsARecord: %n\n"
recordVal;
Printf.printf
"\nproof that thisReturnsA: %n\n"
(thisReturnsA ());
/* Pattern matching */
let blah arg =>
switch arg {
/* Comment before Bar */
| /* Comment between bar/pattern */ Red _ => 1
/* Comment Before non-first bar */
| /* Comment betwen bar/pattern */ Black _ => 0
| Green _ => 0
};
/* Any function that pattern matches a multicase match is interpretted as a
* single arg that is then matched on. Instead of the above `blah` example:*/
let blah =
fun
| Red _ => 1
| Black _ => 0
| Green _ => 1;
/* `fun a => a` is read as "a function that maps a to a". Then the */
/* above example is read: "a function that 'either maps' Red to.. or maps .." */
/* Thc00f564e first bar is read as "either maps" */
/* Curried form is not supported:
let blah x | Red _ => 1 | Black _ => 0;
Theres no sugar rule for dropping => fun, only = fun
*/
/* let blahCurriedX x => fun /* See, nothing says we can drop the => fun */ */
/* |(Red x | Black x | Green x) => 1 /* With some effort, we can ammend the sugar rule that would */ */
/* | Black x => 0 /* Allow us to drop any => fun.. Just need to make pattern matching */ */
/* | Green x => 0; /* Support that */ */
/* */
let blahCurriedX x =>
fun
| Red x
| Black x
| Green x =>
1 /* With some effort, we can ammend the sugar rule that would */
| Black x => 0 /* Allow us to drop any => fun.. Just need to make pattern matching */
| Green x => 0; /* Support that */
let sameThingInLocal = {
let blahCurriedX x =>
fun
| Red x
| Black x
| Green x =>
1 /* With some effort, we can ammend the sugar rule that would */
| Black x => 0 /* Allow us to drop any => fun.. Just need to make pattern matching */
| Green x => 0; /* Support that */
blahCurriedX
};
/* This should be parsed/printed exactly as the previous */
let blahCurriedX x =>
fun
| Red x
| Black x
| Green x => 1
| Black x => 0
| Green x => 0;
/* Any time there are multiple match cases we require a leading BAR */
let v = Red 10;
let Black x | Red x | Green x = v; /* So this NON-function still parses */
/* This doesn't parse, however (and it doesn't in OCaml either):
let | Black x | Red x | Green x = v;
*/
print_int x;
/* Scoping: Let sequences. Familiar syntax for lexical ML style scope and
sequences. */
let res = {
let a = "a starts out as";
{
print_string a;
let a = 20;
print_int a
};
print_string a
};
let res = {
let a = "first its a string";
let a = 20;
print_int a;
print_int a;
print_int a
};
let res = {
let a = "a is always a string";
print_string a;
let b = 30;
print_int b
};
/* let result = LyList.map (fun | [] => true | _ => false) []; */
/* OTHERWISE: You cannot tell if a is the first match case falling through or
* a curried first arg */
/* let blah = fun a | patt => 0 | anotherPatt => 1; */
/* let blah a patt => 0 | anotherPatt => 1; */
/*simple pattern EQUALGREATER expr */
let blah a {blahBlah} => a;
/* match_case */
/* pattern EQUALGREATER expr */
let blah =
fun
| Red _ => 1
| Black _ => 0
| Green _ => 0;
/* Won't work! */
/* let arrowFunc = fun a b => print_string "returning aplusb from arrow"; a + b;; */
let arrowFunc a b => {
print_string "returning aplusb from arrow";
a + b
};
let add a b => {
let extra = {
print_string "adding";
0
};
let anotherExtra = 0;
extra + a + b + anotherExtra
};
print_string (string_of_int (add 4 34));
let dummy _ => 10;
dummy res1;
dummy res2;
dummy res3;
/* Some edge cases */
let myFun firstArg (Red x | Black x | Green x) =>
firstArg + x;
let matchesWithWhen a =>
switch a {
| Red x when 1 > 0 => 10
| Red _ => 10
| Black x => 10
| Green x => 10
};
let matchesWithWhen =
fun
| Red x when 1 > 0 => 10
| Red _ => 10
| Black x => 10
| Green x => 10;
let matchesOne (`Red x) => 10;
/*
Typical OCaml would make you *wrap the functions in parens*! This is because it
can't tell if a semicolon is a sequence operator. Even if we had records use
commas to separate fields,
*/
type adders = {
addTwoNumbers: int => int => int,
addThreeNumbers: int => int => int => int,
addThreeNumbersTupled: (int, int, int) => int
};
let myRecordWithFunctions = {
addTwoNumbers: fun a b => a + b,
addThreeNumbers: fun a b c => a + b + c,
addThreeNumbersTupled: fun (a, b, c) =>
a + b + c
};
let result =
myRecordWithFunctions.addThreeNumbers 10 20 30;
let result =
myRecordWithFunctions.addThreeNumbersTupled (
10,
20,
30
);
let lookTuplesRequireParens = (1, 2);
/* let thisDoesntParse = 1, 2; */
let tupleInsideAParenSequence = {
print_string "look, a tuple inside a sequence";
let x = 10;
(x, x)
};
let tupleInsideALetSequence = {
print_string "look, a tuple inside a sequence";
let x = 10;
(x, x)
};
/* We *require* that function return types be wrapped in
parenthesis. In this example, there's no ambiguity */
let makeIncrementer (delta: int) :(int => int) =>
fun a => a + delta;
/* We could even force that consistency with let bindings - it's allowed
currently but not forced.
*/
let myAnnotatedValBinding: int = 10;
/* Class functions (constructors) and methods are unified in the same way */
class classWithNoArg = {
method x = 0;
method y = 0;
};
/* This parses but doesn't type check
class myClass init => object
method x => init
method y => init
end;
*/
let myFunc (a: int) (b: int) :(int, int) => (
a,
b
);
let myFunc (a: int) (b: int) :list int => [1];
let myFunc (a: int) (b: int) :point => {
x: a,
y: b
};
let myFunc (a: int, b: int) :point => {
x: a,
y: b
};
type myThing = (int, int);
type stillARecord = {name: string, age: int};
/* Rebase latest OCaml to get the following: And fixup
`generalized_constructor_arguments` according to master. */
/* type ('a, 'b) myOtherThing = Leaf {first:'a, second: 'b} | Null; */
type branch 'a 'b = {first: 'a, second: 'b};
type myOtherThing 'a 'b =
| Leaf (branch 'a 'b)
| Null;
type yourThing = myOtherThing int int;
/* Conveniently - this parses exactly how you would intend! No *need* to wrap
in an extra [], but it doesn't hurt */
/* FIXME type lookAtThesePolyVariants = list [`Red] ; */
/* FIXME type bracketsGroupMultipleParamsAndPrecedence = list (list (list [`Red])); */
/* FIXME type youCanWrapExtraIfYouWant = (list [`Red]); */
/* FIXME type hereAreMultiplePolyVariants = list [`Red | `Black]; */
/* FIXME type hereAreMultiplePolyVariantsWithOptionalWrapping = list ([`Red | `Black]); */
/*
/* Proposal: ES6 style lambdas: */
/* Currying */
let lookES6Style = (`Red x) (`Black y) => { };
let lookES6Style (`Red x) (`Black y) => { };
/* Matching the single argument */
let lookES6Style = oneArg => match oneArg with
| `Red x => x
| `Black x => x;
/* The "trick" to currying that we already have is basically the same - we just
* have to reword it a bit:
* From:
* "Any time you see [let x = fun ...] just replace it with [let x ...]"
* To:
* "Any time you see [let x = ... => ] just replace it with [let x ... => ]"
*/
let lookES6Style oneArg => match oneArg with
| `Red x => x
| `Black x => x;
*/
/** Current OCaml Named Arguments. Any aliasing is more than just aliasing!
OCaml allows full on pattern matching of named args. */
/*
A: let named ~a ~b = aa + bb in
B: let namedAlias ~a:aa ~b:bb = aa + bb in
C: let namedAnnot ~(a:int) ~(b:int) = a + b in
D: let namedAliasAnnot ~a:(aa:int) ~b:(bb:int) = aa + bb in
E: let optional ?a ?b = 10 in
F: let optionalAlias ?a:aa ?b:bb = 10 in
G: let optionalAnnot ?(a:int option) ?(b:int option) = 10 in
H: let optionalAliasAnnot ?a:(aa:int option) ?b:(bb:int option) = 10 in
/*
Look! When a default is provided, annotation causes inferred type of argument
to not be "option" since it's automatically destructured (because we know it
will always be available one way or another.)
*/
I: let defOptional ?(a=10) ?(b=10) = 10 in
J: let defOptionalAlias ?a:(aa=10) ?b:(bb=10) = 10 in
K: let defOptionalAnnot ?(a:int=10) ?(b:int=10) = 10 in
\ \
\label_let_pattern opt_default: no longer needed in SugarML
L: let defOptionalAliasAnnot ?a:(aa:int=10) ?b:(bb:int=10) = 10 in
\ \
\let_pattern: still a useful syntactic building block in SugarML
*/
/**
* In Reason, the syntax for named args uses double semicolon, since
* the syntax for lists uses ES6 style [], freeing up the ::.
*/
let a = 10;
let b = 20;
/*A*/
let named a::a b::b => a + b;
type named = a::int => b::int => int;
/*B*/
let namedAlias a::aa b::bb => aa + bb;
let namedAlias a::aa b::bb => aa + bb;
type namedAlias = a::int => b::int => int;
/*C*/
let namedAnnot a::(a: int) b::(b: int) => 20;
/*D*/
let namedAliasAnnot a::(aa: int) b::(bb: int) => 20;
/*E*/
let myOptional a::a=? b::b=? () => 10;
type named = a::int? => b::int? => unit => int;
/*F*/
let optionalAlias a::aa=? b::bb=? () => 10;
/*G*/
let optionalAnnot a::(a: int)=? b::(b: int)=? () => 10;
/*H*/
let optionalAliasAnnot
a::(aa: int)=?
b::(bb: int)=?
() => 10;
/*I: */
let defOptional a::a=10 b::b=10 () => 10;
type named = a::int? => b::int? => unit => int;
/*J*/
let defOptionalAlias a::aa=10 b::bb=10 () => 10;
/*K*/
let defOptionalAnnot
a::(a: int)=10
b::(b: int)=10
() => 10;
/*L*/
let defOptionalAliasAnnot
a::(aa: int)=10
b::(bb: int)=10
() => 10;
/*M: Invoking them - Punned */
let resNotAnnotated = named a::a b::b;
/*N:*/
let resAnnotated: int = named a::a b::b;
/*O: Invoking them */
let resNotAnnotated = named a::a b::b;
/*P: Invoking them */
let resAnnotated: int = named a::a b::b;
/*Q: Here's why "punning" doesn't work! */
/* Is b:: punned with a final non-named arg, or is b:: supplied b as one named arg? */
let b = 20;
let resAnnotated = named a::a b::b;
/*R: Proof that there are no ambiguities with return values being annotated */
let resAnnotated: ty = named a::a b;
/*S: Explicitly passed optionals are a nice way to say "use the default value"*/
let explictlyPassed =
myOptional a::?None b::?None;
/*T: Annotating the return value of the entire function call */
let explictlyPassedAnnotated: int =
myOptional a::?None b::?None;
/*U: Explicitly passing optional with identifier expression */
let a = None;
let explictlyPassed = myOptional a::?a b::?None;
let explictlyPassedAnnotated: int =
myOptional a::?a b::?None;
let nestedLet = {
let _ = 1;
()
};
let nestedLet = {
let _ = 1;
()
};
let nestedLet = {
let _ = 1;
()
};
let nestedLet = {
let _ = 1;
2
};
/*
* Showing many combinations of type annotations and named arguments.
*/
type typeWithNestedNamedArgs =
outerOne::(
innerOne::int => innerTwo::int => int
) =>
outerTwo::int =>
int;
type typeWithNestedOptionalNamedArgs =
outerOne::
(innerOne::int => innerTwo::int => int)? =>
outerTwo::int? =>
int;
type typeWithNestedOptionalNamedArgs =
outerOne::list string? => outerTwo::int? => int;
let x =
callSomeFunction
withArg::10 andOtherArg::wrappedArg;
let res = {
(constraintedSequenceItem: string);
(dontKnowWheYoudWantToActuallyDoThis: string)
};
let res = {
(
butTheyWillBePrintedWithAppropriateSpacing: string
);
(soAsToInstillBestDevelopmentPractices: string)
};
let x = [
(eachItemInListCanBeAnnotated: int),
(typeConstraints: float),
(
tupleConstraints: int,
andNotFunctionInvocations: int
)
];
let x = [
(butWeWillPrint: int),
(themAsSpaceSeparated: float),
(toInfluenceYour: int, developmentHabbits: int)
];
let newRecord = {
...(annotatedSpreadRecord: someRec),
x: y
};
let newRecord = {
...(annotatedSpreadRecord: someRec),
blah: 0,
foo: 1
};
let newRecord = {
...(
youCanEvenCallMethodsHereAndAnnotate them: someRec
),
blah: 0,
foo: 1
};
let newRecord = {
...(
youCanEvenCallMethodsHereAndAnnotate
them named::10: someRec
),
blah: 0,
foo: 1
};
let something: thing blah = aTypeAnnotation;
let something: thing blah = thisIsANamedArg;
let something: thing blah = aTypeAnnotation;
let something: blah = thisIsANamedArg thing;
let something: blah = typeAnnotation thing;
let newRecord = {
...(
heresAFunctionWithNamedArgs argOne::i: annotatedResult
),
soAsToInstill: 0,
developmentHabbits: 1
};
[@@@thisIsAThing];
let x = 10;
/* Ensure that the parenthesis are preserved here because they are
* important:
*/
let something =
fun
| None => (
fun
| [] => "emptyList"
| [_, ..._] => "nonEmptyList"
)
| Some _ => (
fun
| [] => "emptyList"
| [_, ..._] => "nonEmptyList"
);
/* A | B = X; */
let A | B = X;
/* A | (B | C) = X; */
let A | (B | C) = X;
/* (A | B) | (C | D) = X; */
let A | B | (C | D) = X;
/* A | B | (C | D) = X; */
let A | B | (C | D) = X;
/* (A | B) | C = X; */
let A | B | C = X;
/* A | B | C = X; */
let A | B | C = X;
/** External function declaration
*
*/
external f : int => int = "foo";
let x = {contents: 0};
let unitVal = x.contents = 210;

View File

@@ -0,0 +1,19 @@
-\*-
(?:
\s*
(?= [^:;\s]+ \s* -\*-)
|
(?:
.*?[;\s]
|
(?<=-\*-)
)
mode\s*:\s*
)
([^:;\s]+)
(?=
[\s;] | (?<![-*]) -\*-
)
.*?
-\*-

View File

@@ -0,0 +1,27 @@
(?:
(?:\s|^)
vi
(?:m[<=>]?\d+|m)?
|
[\t\x20]
ex
)
(?=
: (?=\s* set? \s [^\n:]+ :) |
: (?!\s* set? \s)
)
(?:
(?:\s|\s*:\s*)
\w*
(?:
\s*=
(?:[^\n\\\s]|\\.)*
)?
)*
[\s:]
(?:filetype|ft|syntax)
\s*=
(MODE_NAME_HERE)
(?=\s|:|$)

View File

@@ -0,0 +1 @@
\b(\d*1[1-3]th|\d*0th|(?:(?!11st)\d)*1st|\d*2nd|(?:(?!13rd)\d*)3rd|\d*[4-9]th)\b

View File

@@ -0,0 +1 @@
/^([^\/#\?]*:?\/\/)?(\/?(?:[^\/#\?]+\/)*)?([^\/#\?]+)?(?:\/(?=$))?(\?[^#]*)?(#.*)?$/

Some files were not shown because too many files have changed in this diff Show More