--- /dev/null
+{
+ "ada": {
+ "dir": "ada",
+ "name": "Ada",
+ "syntax": "Algol",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 9,
+ "perf2": 28,
+ "perf3": 1089,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 5942,
+ "files": 29,
+ "author_name": "Chris Moore",
+ "author_url": "https://github.com/zmower",
+ "lloc": 3759
+ },
+ "awk": {
+ "dir": "awk",
+ "name": "GNU Awk",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 14,
+ "perf2": 47,
+ "perf3": 702,
+ "star_count": 355,
+ "rank": 50,
+ "sloc": 5213,
+ "files": 17,
+ "author_name": "Miutsuru Kariya",
+ "author_url": "https://github.com/kariya-mitsuru",
+ "lloc": 0
+ },
+ "bash": {
+ "dir": "bash",
+ "name": "Bash 4",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 1681,
+ "perf2": 7748,
+ "perf3": 5,
+ "star_count": 59906,
+ "rank": 14,
+ "sloc": 2392,
+ "files": 18,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "basic": {
+ "dir": "basic",
+ "name": "BASIC",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [
+ "cbm",
+ "qbasic"
+ ],
+ "perf1": 11,
+ "perf2": 49,
+ "perf3": 871,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 3963,
+ "files": 23,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 3956
+ },
+ "c": {
+ "dir": "c",
+ "name": "C",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 0.9,
+ "perf2": 2,
+ "perf3": 17211,
+ "star_count": 90804,
+ "rank": 9,
+ "sloc": 3701,
+ "files": 26,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 2012
+ },
+ "cpp": {
+ "dir": "cpp",
+ "name": "C++",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 0.9,
+ "perf2": 1,
+ "perf3": 16045,
+ "star_count": 139366,
+ "rank": 6,
+ "sloc": 3532,
+ "files": 29,
+ "author_name": "Stephen Thirlwall",
+ "author_url": "https://github.com/sdt",
+ "lloc": 1617
+ },
+ "cs": {
+ "dir": "cs",
+ "name": "C#",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 9,
+ "perf2": 10,
+ "perf3": 14958,
+ "star_count": 76670,
+ "rank": 10,
+ "sloc": 3396,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1760
+ },
+ "chuck": {
+ "dir": "chuck",
+ "name": "ChucK",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 35,
+ "perf2": 113,
+ "perf3": 132,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 4962,
+ "files": 98,
+ "author_name": "Vasilij Schneidermann",
+ "author_url": "https://github.com/wasamasa",
+ "lloc": 1796
+ },
+ "clojure": {
+ "dir": "clojure",
+ "name": "Clojure",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [
+ "clj",
+ "cljs"
+ ],
+ "perf1": 25,
+ "perf2": 66,
+ "perf3": 2373,
+ "star_count": 5502,
+ "rank": 27,
+ "sloc": 1207,
+ "files": 23,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "coffee": {
+ "dir": "coffee",
+ "name": "CoffeeScript",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 7,
+ "perf2": 33,
+ "perf3": 18111,
+ "star_count": 8569,
+ "rank": 22,
+ "sloc": 1073,
+ "files": 21,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "common-lisp": {
+ "dir": "common-lisp",
+ "name": "Common Lisp",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 1,
+ "perf2": 2,
+ "perf3": 14665,
+ "star_count": 1146,
+ "rank": 38,
+ "sloc": 2607,
+ "files": 22,
+ "author_name": "Iqbal Ansari",
+ "author_url": "https://github.com/iqbalansari",
+ "lloc": 0
+ },
+ "crystal": {
+ "dir": "crystal",
+ "name": "Crystal",
+ "syntax": "OTHER",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 1,
+ "perf2": 2,
+ "perf3": 28255,
+ "star_count": 938,
+ "rank": 41,
+ "sloc": 2157,
+ "files": 18,
+ "author_name": "Linda_pp",
+ "author_url": "https://github.com/rhysd",
+ "lloc": 0
+ },
+ "d": {
+ "dir": "d",
+ "name": "D",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 0.9,
+ "perf2": 2,
+ "perf3": 15621,
+ "star_count": 653,
+ "rank": 45,
+ "sloc": 2979,
+ "files": 18,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 1434
+ },
+ "dart": {
+ "dir": "dart",
+ "name": "Dart",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 14,
+ "perf2": 38,
+ "perf3": 509,
+ "star_count": 2498,
+ "rank": 34,
+ "sloc": 2279,
+ "files": 18,
+ "author_name": "Harry Terkelsen",
+ "author_url": "https://github.com/hterkelsen",
+ "lloc": 1142
+ },
+ "elixir": {
+ "dir": "elixir",
+ "name": "Elixir",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 14,
+ "perf2": 52,
+ "perf3": 765,
+ "star_count": 6115,
+ "rank": 24,
+ "sloc": 1824,
+ "files": 20,
+ "author_name": "Martin Ek",
+ "author_url": "https://github.com/ekmartin",
+ "lloc": 0
+ },
+ "elm": {
+ "dir": "elm",
+ "name": "Elm",
+ "syntax": "ML",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 69,
+ "perf2": 167,
+ "perf3": 801,
+ "star_count": 809,
+ "rank": 43,
+ "sloc": 5775,
+ "files": 24,
+ "author_name": "Jos van Bakel",
+ "author_url": "https://github.com/c0deaddict",
+ "lloc": 0
+ },
+ "elisp": {
+ "dir": "elisp",
+ "name": "Emacs Lisp",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 16,
+ "perf2": 77,
+ "perf3": 593,
+ "star_count": 5689,
+ "rank": 26,
+ "sloc": 1982,
+ "files": 20,
+ "author_name": "Vasilij Schneidermann",
+ "author_url": "https://github.com/wasamasa",
+ "lloc": 0
+ },
+ "erlang": {
+ "dir": "erlang",
+ "name": "Erlang",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 53,
+ "perf2": 175,
+ "perf3": 175,
+ "star_count": 2942,
+ "rank": 31,
+ "sloc": 2215,
+ "files": 18,
+ "author_name": "Nathan Fiedler",
+ "author_url": "https://github.com/nlfiedler",
+ "lloc": 0
+ },
+ "es6": {
+ "dir": "es6",
+ "name": "ES6",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 3,
+ "perf2": 21,
+ "perf3": 12079,
+ "star_count": 668062,
+ "rank": 2,
+ "sloc": 1230,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "fsharp": {
+ "dir": "fsharp",
+ "name": "F#",
+ "syntax": "ML",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 35,
+ "perf2": 29,
+ "perf3": 20634,
+ "star_count": 950,
+ "rank": 39,
+ "sloc": 3033,
+ "files": 22,
+ "author_name": "Peter Stephens",
+ "author_url": "https://github.com/pstephens",
+ "lloc": 404
+ },
+ "factor": {
+ "dir": "factor",
+ "name": "Factor",
+ "syntax": "Stack",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 2,
+ "perf2": 1,
+ "perf3": 27766,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1305,
+ "files": 33,
+ "author_name": "Jordan Lewis",
+ "author_url": "https://github.com/jordanlewis",
+ "lloc": 0
+ },
+ "fantom": {
+ "dir": "fantom",
+ "name": "Fantom",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 14,
+ "perf2": 31,
+ "perf3": 40400,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1768,
+ "files": 31,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 0
+ },
+ "forth": {
+ "dir": "forth",
+ "name": "Forth",
+ "syntax": "Stack",
+ "type_check": "OTHER",
+ "modes": [],
+ "perf1": 4,
+ "perf2": 14,
+ "perf3": 2448,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 3351,
+ "files": 21,
+ "author_name": "Chris Houser",
+ "author_url": "https://github.com/chouser",
+ "lloc": 0
+ },
+ "guile": {
+ "dir": "guile",
+ "name": "GNU Guile",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 3,
+ "perf2": 9,
+ "perf3": 3962,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1547,
+ "files": 20,
+ "author_name": "Mu Lei",
+ "author_url": "https://github.com/NalaGinrut",
+ "lloc": 0
+ },
+ "gnu-smalltalk": {
+ "dir": "gnu-smalltalk",
+ "name": "GNU Smalltalk",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 14,
+ "perf2": 45,
+ "perf3": 787,
+ "star_count": 152,
+ "rank": 55,
+ "sloc": 2444,
+ "files": 21,
+ "author_name": "Vasilij Schneidermann",
+ "author_url": "https://github.com/wasamasa",
+ "lloc": 0
+ },
+ "go": {
+ "dir": "go",
+ "name": "Go",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 1,
+ "perf2": 3,
+ "perf3": 10334,
+ "star_count": 215511,
+ "rank": 5,
+ "sloc": 3451,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1792
+ },
+ "groovy": {
+ "dir": "groovy",
+ "name": "Groovy",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 477,
+ "perf2": 746,
+ "perf3": 324,
+ "star_count": 4302,
+ "rank": 29,
+ "sloc": 1598,
+ "files": 19,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "haskell": {
+ "dir": "haskell",
+ "name": "Haskell",
+ "syntax": "ML",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 3,
+ "perf2": 8,
+ "perf3": 4338,
+ "star_count": 6312,
+ "rank": 23,
+ "sloc": 2011,
+ "files": 18,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "haxe": {
+ "dir": "haxe",
+ "name": "Haxe",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [
+ "neko",
+ "python",
+ "cpp",
+ "js"
+ ],
+ "perf1": 5,
+ "perf2": 26,
+ "perf3": 15377,
+ "star_count": 580,
+ "rank": 46,
+ "sloc": 2270,
+ "files": 23,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1045
+ },
+ "hy": {
+ "dir": "hy",
+ "name": "Hy",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 17,
+ "perf2": 67,
+ "perf3": 585,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1215,
+ "files": 18,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "io": {
+ "dir": "io",
+ "name": "Io",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 357,
+ "perf2": 1333,
+ "perf3": 29,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1262,
+ "files": 18,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 0
+ },
+ "java": {
+ "dir": "java",
+ "name": "Java",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 7,
+ "perf2": 24,
+ "perf3": 57275,
+ "star_count": 255160,
+ "rank": 4,
+ "sloc": 3061,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1537
+ },
+ "js": {
+ "dir": "js",
+ "name": "JavaScript",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 3,
+ "perf2": 22,
+ "perf3": 14550,
+ "star_count": 668062,
+ "rank": 1,
+ "sloc": 2779,
+ "files": 33,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "julia": {
+ "dir": "julia",
+ "name": "Julia",
+ "syntax": "Algol",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 253,
+ "perf2": 32,
+ "perf3": 2975,
+ "star_count": 948,
+ "rank": 40,
+ "sloc": 1413,
+ "files": 19,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "kotlin": {
+ "dir": "kotlin",
+ "name": "Kotlin",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 19,
+ "perf2": 75,
+ "perf3": 33381,
+ "star_count": 20958,
+ "rank": 17,
+ "sloc": 1571,
+ "files": 19,
+ "author_name": "Javier Fernandez-Ivern",
+ "author_url": "https://github.com/ivern",
+ "lloc": 0
+ },
+ "livescript": {
+ "dir": "livescript",
+ "name": "LiveScript",
+ "syntax": "ML",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 6,
+ "perf2": 26,
+ "perf3": 7570,
+ "star_count": 116,
+ "rank": 57,
+ "sloc": 2128,
+ "files": 19,
+ "author_name": "Jos van Bakel",
+ "author_url": "https://github.com/c0deaddict",
+ "lloc": 0
+ },
+ "logo": {
+ "dir": "logo",
+ "name": "Logo",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 19182,
+ "perf2": 53948,
+ "perf3": 0.01,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 2139,
+ "files": 20,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 0
+ },
+ "lua": {
+ "dir": "lua",
+ "name": "Lua",
+ "syntax": "Algol",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 10,
+ "perf2": 44,
+ "perf3": 955,
+ "star_count": 8769,
+ "rank": 21,
+ "sloc": 1909,
+ "files": 21,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "make": {
+ "dir": "make",
+ "name": "GNU Make",
+ "syntax": "OTHER",
+ "type_check": "OTHER",
+ "modes": [],
+ "perf1": 5050,
+ "perf2": 31077,
+ "perf3": 1,
+ "star_count": 2034,
+ "rank": 35,
+ "sloc": 1821,
+ "files": 22,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "mal": {
+ "dir": "mal",
+ "name": "mal itself",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 277,
+ "perf2": 1346,
+ "perf3": 40,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 890,
+ "files": 13,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "matlab": {
+ "dir": "matlab",
+ "name": "MATLAB",
+ "syntax": "Algol",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 1709,
+ "perf2": 6295,
+ "perf3": 5,
+ "star_count": 2867,
+ "rank": 32,
+ "sloc": 2204,
+ "files": 27,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "miniMAL": {
+ "dir": "miniMAL",
+ "name": "miniMAL",
+ "syntax": "JSON",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 1340,
+ "perf2": 5383,
+ "perf3": 7,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1691,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "nasm": {
+ "dir": "nasm",
+ "name": "NASM",
+ "syntax": "OTHER",
+ "type_check": "OTHER",
+ "modes": [],
+ "perf1": 0.9,
+ "perf2": 2,
+ "perf3": 24147,
+ "star_count": 1195,
+ "rank": 37,
+ "sloc": 14483,
+ "files": 19,
+ "author_name": "Ben Dudson",
+ "author_url": "https://github.com/bendudson",
+ "lloc": 0
+ },
+ "nim": {
+ "dir": "nim",
+ "name": "Nim",
+ "syntax": "Python",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 1,
+ "perf2": 2,
+ "perf3": 30900,
+ "star_count": 529,
+ "rank": 48,
+ "sloc": 1423,
+ "files": 17,
+ "author_name": "Dennis Felsing",
+ "author_url": "https://github.com/def-",
+ "lloc": 0
+ },
+ "objpascal": {
+ "dir": "objpascal",
+ "name": "Object Pascal",
+ "syntax": "Algol",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 4,
+ "perf2": 12,
+ "perf3": 2830,
+ "star_count": 1324,
+ "rank": 36,
+ "sloc": 6179,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 3971
+ },
+ "objc": {
+ "dir": "objc",
+ "name": "Objective C",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 6,
+ "perf2": 28,
+ "perf3": 1599,
+ "star_count": 48248,
+ "rank": 16,
+ "sloc": 2363,
+ "files": 26,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1059
+ },
+ "ocaml": {
+ "dir": "ocaml",
+ "name": "OCaml",
+ "syntax": "ML",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 1,
+ "perf2": 2,
+ "perf3": 23267,
+ "star_count": 3646,
+ "rank": 30,
+ "sloc": 1269,
+ "files": 17,
+ "author_name": "Chris Houser",
+ "author_url": "https://github.com/chouser",
+ "lloc": 0
+ },
+ "perl": {
+ "dir": "perl",
+ "name": "Perl",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 13,
+ "perf2": 50,
+ "perf3": 790,
+ "star_count": 4679,
+ "rank": 28,
+ "sloc": 2265,
+ "files": 22,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1107
+ },
+ "perl6": {
+ "dir": "perl6",
+ "name": "Perl 6",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 441,
+ "perf2": 1182,
+ "perf3": 23,
+ "star_count": 137,
+ "rank": 56,
+ "sloc": 1238,
+ "files": 18,
+ "author_name": "Hinrik Örn Sigurðsson",
+ "author_url": "https://github.com/hinrik",
+ "lloc": 484
+ },
+ "php": {
+ "dir": "php",
+ "name": "PHP",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 8,
+ "perf2": 28,
+ "perf3": 1268,
+ "star_count": 135579,
+ "rank": 7,
+ "sloc": 1998,
+ "files": 21,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1074
+ },
+ "picolisp": {
+ "dir": "picolisp",
+ "name": "Picolisp",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 2,
+ "perf2": 7,
+ "perf3": 6005,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1366,
+ "files": 20,
+ "author_name": "Vasilij Schneidermann",
+ "author_url": "https://github.com/wasamasa",
+ "lloc": 0
+ },
+ "plpgsql": {
+ "dir": "plpgsql",
+ "name": "PL/pgSQL",
+ "syntax": "Algol",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 478,
+ "perf2": 3830,
+ "perf3": 20,
+ "star_count": 897,
+ "rank": 42,
+ "sloc": 3679,
+ "files": 21,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "plsql": {
+ "dir": "plsql",
+ "name": "PL/SQL",
+ "syntax": "Algol",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 19182,
+ "perf2": 1921,
+ "perf3": 0.01,
+ "star_count": 199,
+ "rank": 53,
+ "sloc": 4180,
+ "files": 21,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "powershell": {
+ "dir": "powershell",
+ "name": "PowerShell",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 1921,
+ "perf2": 7832,
+ "perf3": 5,
+ "star_count": 5795,
+ "rank": 25,
+ "sloc": 1147,
+ "files": 12,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "ps": {
+ "dir": "ps",
+ "name": "PostScript",
+ "syntax": "Stack",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 38,
+ "perf2": 274,
+ "perf3": 198,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 2482,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "python": {
+ "dir": "python",
+ "name": "Python",
+ "syntax": "Python",
+ "type_check": "Dynamic",
+ "modes": [
+ "python2",
+ "python3"
+ ],
+ "perf1": 7,
+ "perf2": 29,
+ "perf3": 1371,
+ "star_count": 336045,
+ "rank": 3,
+ "sloc": 1358,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 1344
+ },
+ "rpython": {
+ "dir": "rpython",
+ "name": "RPython",
+ "syntax": "Python",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 0.9,
+ "perf2": 1,
+ "perf3": 69848,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 2102,
+ "files": 19,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 2096
+ },
+ "r": {
+ "dir": "r",
+ "name": "R",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 78,
+ "perf2": 295,
+ "perf3": 117,
+ "star_count": 2644,
+ "rank": 33,
+ "sloc": 1625,
+ "files": 19,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "racket": {
+ "dir": "racket",
+ "name": "Racket",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 2,
+ "perf2": 7,
+ "perf3": 4865,
+ "star_count": 281,
+ "rank": 51,
+ "sloc": 1193,
+ "files": 18,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "rexx": {
+ "dir": "rexx",
+ "name": "Rexx",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 160,
+ "perf2": 660,
+ "perf3": 61,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 2747,
+ "files": 19,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 0
+ },
+ "ruby": {
+ "dir": "ruby",
+ "name": "Ruby",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 2,
+ "perf2": 8,
+ "perf3": 4163,
+ "star_count": 54043,
+ "rank": 15,
+ "sloc": 1291,
+ "files": 20,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "rust": {
+ "dir": "rust",
+ "name": "Rust",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 0.9,
+ "perf2": 1,
+ "perf3": 16720,
+ "star_count": 19178,
+ "rank": 18,
+ "sloc": 2862,
+ "files": 18,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 714
+ },
+ "scala": {
+ "dir": "scala",
+ "name": "Scala",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 27,
+ "perf2": 66,
+ "perf3": 25785,
+ "star_count": 13634,
+ "rank": 19,
+ "sloc": 1849,
+ "files": 18,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "scheme": {
+ "dir": "scheme",
+ "name": "Scheme (R7RS)",
+ "syntax": "Lisp",
+ "type_check": "Dynamic",
+ "modes": [
+ "chibi",
+ "kawa",
+ "gauche",
+ "chicken",
+ "sagittarius",
+ "cyclone",
+ "foment"
+ ],
+ "perf1": 6,
+ "perf2": 19,
+ "perf3": 2231,
+ "star_count": 718,
+ "rank": 44,
+ "sloc": 1269,
+ "files": 13,
+ "author_name": "Vasilij Schneidermann",
+ "author_url": "https://github.com/wasamasa",
+ "lloc": 0
+ },
+ "skew": {
+ "dir": "skew",
+ "name": "Skew",
+ "syntax": "OTHER",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 6,
+ "perf2": 11,
+ "perf3": 3608,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 1638,
+ "files": 19,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 0
+ },
+ "swift": {
+ "dir": "swift",
+ "name": "Swift 2",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 2,
+ "perf2": 6,
+ "perf3": 5322,
+ "star_count": 66012,
+ "rank": 11,
+ "sloc": 2963,
+ "files": 14,
+ "author_name": "Keith Rollin",
+ "author_url": "https://github.com/keith-rollin",
+ "lloc": 0
+ },
+ "swift3": {
+ "dir": "swift3",
+ "name": "Swift 3",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 8,
+ "perf2": 27,
+ "perf3": 1234,
+ "star_count": 66012,
+ "rank": 12,
+ "sloc": 2362,
+ "files": 17,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "swift4": {
+ "dir": "swift4",
+ "name": "Swift 4",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 5,
+ "perf2": 16,
+ "perf3": 2065,
+ "star_count": 66012,
+ "rank": 13,
+ "sloc": 1767,
+ "files": 17,
+ "author_name": "陆遥",
+ "author_url": "https://github.com/LispLY",
+ "lloc": 0
+ },
+ "tcl": {
+ "dir": "tcl",
+ "name": "Tcl",
+ "syntax": "OTHER",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 24,
+ "perf2": 103,
+ "perf3": 373,
+ "star_count": 171,
+ "rank": 54,
+ "sloc": 2468,
+ "files": 20,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 0
+ },
+ "ts": {
+ "dir": "ts",
+ "name": "TypeScript",
+ "syntax": "C",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 4,
+ "perf2": 14,
+ "perf3": 26534,
+ "star_count": 93555,
+ "rank": 8,
+ "sloc": 2836,
+ "files": 20,
+ "author_name": "Masahiro Wakame",
+ "author_url": "https://github.com/vvakame",
+ "lloc": 0
+ },
+ "vhdl": {
+ "dir": "vhdl",
+ "name": "VHDL",
+ "syntax": "Algol",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 3,
+ "perf2": 9,
+ "perf3": 3342,
+ "star_count": 217,
+ "rank": 52,
+ "sloc": 4258,
+ "files": 19,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 0
+ },
+ "vimscript": {
+ "dir": "vimscript",
+ "name": "Vimscript",
+ "syntax": "Algol",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 219,
+ "perf2": 1055,
+ "perf3": 43,
+ "star_count": 10096,
+ "rank": 20,
+ "sloc": 2147,
+ "files": 22,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 12
+ },
+ "vb": {
+ "dir": "vb",
+ "name": "Visual Basic.NET",
+ "syntax": "Algol",
+ "type_check": "Static",
+ "modes": [],
+ "perf1": 14,
+ "perf2": 14,
+ "perf3": 10121,
+ "star_count": 578,
+ "rank": 47,
+ "sloc": 3839,
+ "files": 19,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 394
+ },
+ "wasm": {
+ "dir": "wasm",
+ "name": "WebAssembly",
+ "syntax": "Lisp",
+ "type_check": "Static",
+ "modes": [
+ "wace_libc",
+ "node",
+ "warpy"
+ ],
+ "perf1": 2,
+ "perf2": 10,
+ "perf3": 3742,
+ "star_count": 365,
+ "rank": 49,
+ "sloc": 5270,
+ "files": 26,
+ "author_name": "Joel Martin",
+ "author_url": "https://github.com/kanaka",
+ "lloc": 0
+ },
+ "yorick": {
+ "dir": "yorick",
+ "name": "Yorick",
+ "syntax": "C",
+ "type_check": "Dynamic",
+ "modes": [],
+ "perf1": 67,
+ "perf2": 288,
+ "perf3": 147,
+ "star_count": null,
+ "rank": 68,
+ "sloc": 2398,
+ "files": 19,
+ "author_name": "Dov Murik",
+ "author_url": "https://github.com/dubek",
+ "lloc": 210
+ }
+}
\ No newline at end of file
--- /dev/null
+headers:
+ - [dir , name , syntax , type_check , modes]
+
+languages:
+ - [ada , Ada , Algol , Static , []]
+ - [awk , GNU Awk , C , Dynamic , []]
+ - [bash , Bash 4 , OTHER , Dynamic , []]
+ - [basic , BASIC , OTHER , Dynamic , [cbm, qbasic]]
+ - [c , C , C , Static , []]
+ - [cpp , C++ , C , Static , []]
+ - [cs , C# , C , Static , []]
+ - [chuck , ChucK , C , Static , []]
+ - [clojure , Clojure , Lisp , Dynamic , [clj, cljs]]
+ - [coffee , CoffeeScript , OTHER , Dynamic , []]
+ - [common-lisp , Common Lisp , Lisp , Dynamic , []]
+ - [crystal , Crystal , OTHER , Static , []]
+ - [d , D , C , Static , []]
+ - [dart , Dart , C , Static , []]
+ - [elixir , Elixir , OTHER , Dynamic , []]
+ - [elm , Elm , ML , Static , []]
+ - [elisp , Emacs Lisp , Lisp , Dynamic , []]
+ - [erlang , Erlang , OTHER , Dynamic , []]
+ - [es6 , ES6 , C , Dynamic , []]
+ - [fsharp , F# , ML , Static , []]
+ - [factor , Factor , Stack , Dynamic , []]
+ - [fantom , Fantom , C , Static , []]
+ - [forth , Forth , Stack , OTHER , []]
+ - [guile , GNU Guile , Lisp , Dynamic , []]
+ - [gnu-smalltalk , GNU Smalltalk , OTHER , Dynamic , []]
+ - [go , Go , C , Static , []]
+ - [groovy , Groovy , C , Dynamic , []]
+ - [haskell , Haskell , ML , Static , []]
+ - [haxe , Haxe , C , Static , [neko,python,cpp,js]]
+ - [hy , Hy , Lisp , Dynamic , []]
+ - [io , Io , OTHER , Dynamic , []]
+ - [java , Java , C , Static , []]
+ - [js , JavaScript , C , Dynamic , []]
+ - [julia , Julia , Algol , Dynamic , []]
+ - [kotlin , Kotlin , C , Static , []]
+ - [livescript , LiveScript , ML , Dynamic , []]
+ - [logo , Logo , OTHER , Dynamic , []]
+ - [lua , Lua , Algol , Dynamic , []]
+ - [make , GNU Make , OTHER , OTHER , []]
+ - [mal , mal itself , Lisp , Dynamic , []]
+ - [matlab , MATLAB , Algol , Dynamic , []]
+ - [miniMAL , miniMAL , JSON , Dynamic , []]
+ - [nasm , NASM , OTHER , OTHER , []]
+ - [nim , Nim , Python , Static , []]
+ - [objpascal , Object Pascal , Algol , Static , []]
+ - [objc , Objective C , C , Static , []]
+ - [ocaml , OCaml , ML , Static , []]
+ - [perl , Perl , C , Dynamic , []]
+ - [perl6 , Perl 6 , C , Dynamic , []]
+ - [php , PHP , C , Dynamic , []]
+ - [picolisp , Picolisp , Lisp , Dynamic , []]
+ - [plpgsql , PL/pgSQL , Algol , Static , []]
+ - [plsql , PL/SQL , Algol , Static , []]
+ - [powershell , PowerShell , OTHER , Dynamic , []]
+ - [ps , PostScript , Stack , Dynamic , []]
+ - [python , Python , Python , Dynamic , [python2,python3]]
+ - [rpython , RPython , Python , Static , []]
+ - [r , R , C , Dynamic , []]
+ - [racket , Racket , Lisp , Dynamic , []]
+ - [rexx , Rexx , OTHER , Dynamic , []]
+ - [ruby , Ruby , OTHER , Dynamic , []]
+ - [rust , Rust , C , Static , []]
+ - [scala , Scala , C , Static , []]
+ - [scheme , Scheme (R7RS) , Lisp , Dynamic , [chibi,kawa,gauche,chicken,sagittarius,cyclone,foment]]
+ - [skew , Skew , OTHER , Static , []]
+ - [swift , Swift 2 , C , Static , []]
+ - [swift3 , Swift 3 , C , Static , []]
+ - [swift4 , Swift 4 , C , Static , []]
+ - [tcl , Tcl , OTHER , Dynamic , []]
+ - [ts , TypeScript , C , Static , []]
+ - [vhdl , VHDL , Algol , Static , []]
+ - [vimscript , Vimscript , Algol , Dynamic , []]
+ - [vb , Visual Basic.NET , Algol , Static , []]
+ - [wasm , WebAssembly , Lisp , Static , [wace_libc,node,warpy]]
+ - [yorick , Yorick , C , Dynamic , []]
--- /dev/null
+#!/usr/bin/env python
+
+const { promisify } = require('util')
+const readFile = promisify(require('fs').readFile)
+const writeFile = promisify(require('fs').writeFile)
+const readdir = promisify(require('fs').readdir)
+const path = require('path')
+const yaml = require('js-yaml')
+const request = require('request-promise-native')
+const exec = promisify(require('child_process').exec)
+
+const VERBOSE = process.env['VERBOSE'] || false
+const BASE_PATH = process.env['BASE_PATH'] || 'base_data.yaml'
+const README_PATH = process.env['README_PATH'] || '../../README.md'
+// GitHut Pushes
+//const GITHUT_URL = 'https://raw.githubusercontent.com/madnight/githut/gh-pages/gh-push-event_eb2696.json'
+// GitHut Stars
+const GITHUT_URL = process.env['GITHUT_URL'] || 'https://raw.githubusercontent.com/madnight/githut/gh-pages/gh-star-event_e61175.json'
+const MAL_PATH = process.env['MAL_PATH'] || '../../'
+
+
+const githutToNames = {
+ 'Awk': ['GNU Awk'],
+ 'Shell': ['Bash 4'],
+ 'JavaScript': ['JavaScript', 'ES6'],
+ 'Makefile': ['GNU Make'],
+ 'Matlab': ['MATLAB'],
+ 'Assembly': ['NASM'],
+ 'Pascal': ['Object Pascal'],
+ 'Objective-C': ['Objective C'],
+ 'PLpgSQL': ['PL/pgSQL'],
+ 'PLSQL': ['PL/SQL'],
+ 'Scheme': ['Scheme (R7RS)'],
+ 'Smalltalk': ['GNU Smalltalk'],
+ 'Swift': ['Swift 2', 'Swift 3', 'Swift 4'],
+ 'Vim script': ['Vimscript'],
+ 'Visual Basic': ['Visual Basic.NET'],
+}
+
+function vlog(...args) {
+ if (VERBOSE) {
+ console.log(...args)
+ }
+}
+
+function die(code, ...args) {
+ console.error(...args)
+ process.exit(code)
+}
+
+async function main() {
+ const logsPath = path.resolve(process.argv[2])
+ const outPath = path.resolve(process.argv[3])
+
+ vlog(`Loading base data yaml from '${BASE_PATH}`)
+ const baseYaml = yaml.safeLoad(await readFile(BASE_PATH, 'utf8'))
+ vlog(`Loading README text from '${README_PATH}`)
+ const readmeLines = (await readFile(README_PATH, 'utf8')).split(/\n/)
+ vlog(`Downloading GitHut HTML from '${GITHUT_URL}`)
+ const githutText = (await request(GITHUT_URL))
+ vlog(`Loading log data from '${logsPath}'`)
+ const logFiles = (await readdir(logsPath))
+ .map(x => parseInt(x))
+ .sort((a, b) => a - b)
+ let logData = []
+ for (const f of logFiles) {
+ if (!(/^[0-9]+$/.exec(f))) { continue }
+ const path = logsPath + "/" + f
+ logData.push([await readFile(path, 'utf8'), path])
+ }
+
+ let dirs = []
+ let names = []
+ let dataList = []
+ let dataByDir = {}
+ let dataByName = {}
+
+ vlog(`Processing base data`)
+ for (let d of baseYaml['languages']) {
+ let data = {'dir': d[0],
+ 'name': d[1],
+ 'syntax': d[2],
+ 'type_check': d[3],
+ 'modes': d[4],
+ 'perf1': null,
+ 'perf2': null,
+ 'perf3': 0,
+ 'star_count': null,
+ 'rank': null,
+ 'sloc': 0,
+ 'files': 0}
+ dirs.push(d[0])
+ names.push(d[1])
+ dataList.push(data)
+ dataByDir[d[0]] = data
+ dataByName[d[1]] = data
+ }
+
+ vlog(`Processing README implementations table`)
+ const readme_re = /^\| \[([^\[]*)\].* \| \[([^|]*)\]\(([^|]*)\) *\| *$/
+ for (let row of readmeLines.filter(l => /^\| [\[]/.exec(l))) {
+ t = readme_re.exec(row)
+ if (t) {
+ if (t[1] in dataByName) {
+ let data = dataByName[t[1]]
+ data.author_name = t[2]
+ data.author_url = t[3]
+ } else {
+ die(1, `README language '${t[1]}' not found in base data`)
+ }
+ } else {
+ die(1, `No match for README table row: ${row}`)
+ }
+ }
+
+ vlog(`Processing GitHut data`)
+ const gdata = githutText.split(/\n/)
+ .map(JSON.parse)
+ .filter(d => d.year === "2018" && d.quarter === '4')
+ .map(d => (d.count = parseInt(d.count), d))
+ .sort((a,b) => (a.count > b.count) ? -1 : a.count < b.count ? 1 : 0)
+ let curRank = 1
+ for (let gitem of gdata) {
+ const names = githutToNames[gitem.name] || [gitem.name]
+ for (let name of names) {
+ if (name in dataByName) {
+ dataByName[name].star_count = gitem.count
+ dataByName[name].rank = curRank
+ vlog(` ${dataByName[name].dir} stars: ${gitem.count}, rank: ${curRank}`)
+ curRank += 1
+ } else {
+ vlog(` ignoring GitHut language ${name}`)
+ }
+ }
+ }
+
+ vlog(`Processing log file data`)
+ const perf_run_re = /Running:.*\.\.\/tests\/(perf[0-9])\.mal/
+ const perf_num_re = /Elapsed time: ([0-9.]+) msecs|iters over 10 seconds: ([0-9]+)/
+ for (let [log, file] of logData) {
+ const dir_match = (/export IMPL=(\S+)/i).exec(log)
+ if (!dir_match) { die(1, `no IMPL found in ${file}`) }
+ const dir = dir_match[1]
+ const data = dataByDir[dir]
+// if (data.perf1 !== null) {
+// vlog(` ${dir} already has perf data, ignoring ${file}`)
+// continue
+// }
+ const perfs = {}
+ const logLines = log.split(/\n/)
+ for (let i = 0; i < logLines.length; i++) {
+ const match_run = perf_run_re.exec(logLines[i])
+ if (match_run) {
+ // Find the result line
+ let match_num = null
+ do {
+ i += 1
+ match_num = perf_num_re.exec(logLines[i])
+ if (match_num) {
+ num = parseFloat(match_num[1] || match_num[2], 10)
+ perfs[match_run[1]] = num
+ }
+ } while ((!match_num) && i < logLines.length)
+ }
+ }
+ if ((perfs.perf3 > data.perf3) || !data.perf3) {
+ data.perf1 = perfs.perf1
+ data.perf2 = perfs.perf2
+ data.perf3 = perfs.perf3
+ vlog(` ${dir}: ${perfs.perf1}, ${perfs.perf2}, ${perfs.perf3}`)
+ } else {
+ vlog(` ${dir}: ${perfs.perf1}, ${perfs.perf2}, ${perfs.perf3} (perf3 is worse, ignoring ${file})`)
+ }
+ }
+
+ vlog(`Gathering LOC stats`)
+ const stat_re = /SLOC=([0-9]+).*LLOC=([0-9]+).*in ([0-9]+) files/
+ process.chdir(MAL_PATH)
+ for (let data of dataList) {
+ vlog(` gathering stats information for ${data.dir}`)
+ const { stdout, stderr } = await exec(`make "stats^${data.dir}"`)
+ const match = stat_re.exec(stdout.split(/\n/)[1])
+ data.sloc = parseInt(match[1], 10)
+ data.lloc = parseInt(match[2], 10)
+ data.files = parseInt(match[3], 10)
+ }
+
+ vlog(`Filling in missing attributes`)
+ // leave a gap between actual ranked implementations and those
+ // with no rankings
+ maxRank = curRank + 10
+ maxPerf1 = dataList.reduce((a, d) => d.perf1 > a ? d.perf1 : a, 0)
+ maxPerf2 = dataList.reduce((a, d) => d.perf2 > a ? d.perf1 : a, 0)
+ for (let d of dataList) {
+ if (d.rank === null) {
+ vlog(` setting rank to ${maxRank} for ${d.dir}`)
+ d.rank = maxRank
+ }
+ if (d.perf1 === null) {
+ vlog(` setting perf1 to ${maxPerf1} for ${d.dir}`)
+ d.perf1 = maxPerf1
+ }
+ if (d.perf2 === null) {
+ vlog(` setting perf2 to ${maxPerf2} for ${d.dir}`)
+ d.perf2 = maxPerf2
+ }
+ }
+
+ vlog(`Adjusting perf numbers to avoid 0`)
+ for (let d of dataList) {
+ if (d.perf1 === 0) { d.perf1 = 0.9 }
+ if (d.perf2 === 0) { d.perf2 = 0.9 }
+ if (d.perf3 === 0) { d.perf3 = 0.01 }
+ }
+
+ vlog(`Writing full lanaguage data to ${outPath}`)
+ await writeFile(outPath, JSON.stringify(dataByDir, null, 2))
+
+ process.exit(0)
+}
+
+main()
--- /dev/null
+const malColors = [
+ "#1f77b4","#bf7f0e","#4cb00c","#b62728","#9467bd","#bc664b","#b377c2","#0fbf5f","#bcbd22","#17beef",
+ "#1f6784","#8f7f0e","#4c800c","#862728","#54678d","#8c564b","#8377c2","#0f8f5f","#8c8d22","#178eef",
+ "#1f97d4","#ff7f0e","#4cf00c","#f62728","#c467fd","#fc764b","#f377c2","#0fff5f","#fcfd22","#17feef",
+]
+
+const axisSet = new Set(['perf1', 'perf2', 'perf3', 'rank', 'sloc', 'files'])
+const colorSet = new Set(['type_check', 'syntax', 'author_name'])
+const perfSet = new Set(['perf1', 'perf2', 'perf3'])
+const invertSet = new Set(['rank', 'perf1', 'perf2'])
+const perfLogSet = new Set(['perf1', 'perf2', 'sloc', 'files'])
+
+let cfg = {
+ ckey: 'syntax',
+ xkey: 'rank',
+ ykey: 'perf3',
+ skey: 'sloc',
+
+ xlog: false,
+ ylog: true,
+}
+
+let allData
+let graphData = []
+let chart
+
+//
+// Util functions
+//
+
+function malExtent(data, key) {
+ let extent = d3.extent(Object.values(data), d => d[key])
+ // pad the bottom rank so it's not on the opposite axis line
+ if (key === 'rank') {
+ extent[0] = 0.99 // Setting this to 1 breaks log scale render
+ extent[extent.length-1] += 1
+ }
+ // Replace 0's with 0.01 to prevent divide by zero errors
+ if (extent[0] === 0) { extent[0] = 0.0001 }
+ if (extent[extent.length-1] === 0) { extent[extent.length-1] = 0.0001 }
+ // For rank, perf1 and perf2 reverse the Axis range
+ if (invertSet.has(key)) {
+ extent.reverse()
+ }
+ return extent
+}
+
+function malScale(log) {
+ return log ? d3.scale.log() : d3.scale.linear()
+}
+
+function malTickValues(key, log) {
+ if (log && perfSet.has(key)) {
+ return [1, 10, 100, 1000, 10000, 100000]
+ } else {
+ return null
+ }
+}
+
+function malCircleSize(key, min, max, val) {
+ let size = (val || 0.01) - (min - 0.01)
+ if (invertSet.has(key)) {
+ size = (max + 0.01) - size
+ }
+// if (perfLogSet.has(key)) {
+// size = Math.log(size)
+// }
+// console.log(key, max, val, size)
+ return size
+}
+
+
+//
+// UI / Axis Data / query parameters
+//
+
+// Parser query string and update cfg map with valid config options
+(function parseQuery(q) {
+ const pairs = (q[0] === '?' ? q.substr(1) : q).split('&')
+ for (const [p1, p2] of pairs.map(p => p.split('='))) {
+ let k = decodeURIComponent(p1).toLowerCase()
+ let v = p2 ? decodeURIComponent(p2) : true
+ if (v in {"true":1,"1":1,"yes":1}) { v = true }
+ if (v in {"false":1,"0":1,"no":1}) { v = false }
+ if (k in cfg && (axisSet.has(v) || colorSet.has(v))) {
+ cfg[k] = v
+ }
+ if ((new Set(['xlog', 'ylog'])).has(k) && typeof v === 'boolean') {
+ cfg[k] = v
+ }
+ }
+})(location.search)
+
+// Set the checked elements based on the the cfg
+for (const key of Object.keys(cfg)) {
+ for (const node of document.getElementsByName(key)) {
+ let val = node.value
+ if (val in {"true":1,"1":1,"yes":1}) { val = true }
+ if (val in {"false":1,"0":1,"no":1}) { val = false }
+ if (val === cfg[key]) {
+ node.checked = true
+ } else {
+ node.checked = false
+ }
+ }
+}
+
+// Add onchange to all selector radio buttons/check boxes
+for (let input of document.getElementsByClassName('selects')) {
+ input.addEventListener('change', function(evt) {
+ if (new Set(['xlog', 'ylog']).has(evt.target.name)) {
+ cfg[evt.target.name] = evt.target.checked
+ } else {
+ cfg[evt.target.name] = evt.target.value
+ }
+ const query = Object.entries(cfg).map(([k,v]) => k + "=" + v).join('&')
+ history.pushState(null, '', '?' + query)
+ updateGraphData()
+ })
+}
+
+
+//
+// Graph rendering / updating
+//
+
+function updateGraphData() {
+ let xMax = 0
+ let yMax = 0
+ let sMin = null
+ let sMax = null
+ const colorSet = new Set(Object.values(allData).map(d => d[cfg.ckey]))
+ const colorList = Array.from(colorSet.values())
+ // empty the graphData without recreating it
+ while (graphData.length > 0) { graphData.pop() }
+ graphData.push(...colorList.map(t => ({key: t, values: []})))
+ for (var dir of Object.keys(allData)) {
+ const impl = allData[dir]
+ if (impl[cfg.xkey] > xMax) { xMax = impl[cfg.xkey] }
+ if (impl[cfg.ykey] > yMax) { yMax = impl[cfg.ykey] }
+ if (sMin === null) { sMin = impl[cfg.skey] }
+ if (impl[cfg.skey] < sMin) { sMin = impl[cfg.skey] }
+ if (impl[cfg.skey] > sMax) { sMax = impl[cfg.skey] }
+ }
+ for (var dir of Object.keys(allData)) {
+ const impl = allData[dir]
+ // Invert size for inverted data
+ graphData[colorList.indexOf(impl[cfg.ckey])].values.push({
+ x: impl[cfg.xkey] || 0,
+ y: impl[cfg.ykey] || 0,
+ size: malCircleSize(cfg.skey, sMin, sMax, impl[cfg.skey]),
+ shape: 'circle',
+ label: impl.name,
+ impl: impl,
+ })
+ }
+
+ // Update the axes domain, scale and tick values
+ chart.xDomain(malExtent(allData, cfg.xkey))
+ chart.yDomain(malExtent(allData, cfg.ykey))
+ chart.xScale(malScale(cfg.xlog))
+ chart.yScale(malScale(cfg.ylog))
+ chart.xAxis.tickValues(malTickValues(cfg.xkey, cfg.xlog))
+ chart.yAxis.tickValues(malTickValues(cfg.ykey, cfg.ylog))
+
+ // Update the graph
+ d3.select('#mal svg')
+ .data([graphData])
+ .transition().duration(350).ease('linear')
+ .call(chart)
+
+ chart.update()
+
+ nv.utils.windowResize(chart.update)
+}
+
+nv.addGraph(function() {
+ chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLabels(true)
+ .duration(300)
+ .color(malColors)
+ chart.dispatch.on('renderEnd', function() {
+ console.log('render complete')
+ })
+ chart.dispatch.on('stateChange', function(e) {
+ nv.log('New State:', JSON.stringify(e))
+ })
+ chart.tooltip.contentGenerator(function(obj) {
+ const i = obj.point.impl
+ return '<h3>' + i.name + '</h3>' +
+ '<p class="impl-data">' +
+ '<b>Syntax Style</b>: ' + i.syntax + '<br>' +
+ '<b>Type Discipline</b>: ' + i.type_check + '<br>' +
+ '<b>Github Stars</b>: ' + (i.star_count || 'unknown') + '<br>' +
+ '<b>GitHut Relative Rank</b>: ' + i.rank + '<br>' +
+ '<br>' +
+ '<b>Perf 1</b>: ' + i.perf1 + ' ms<br>' +
+ '<b>Perf 2</b>: ' + i.perf2 + ' ms<br>' +
+ '<b>Perf 3</b>: ' + i.perf3 + ' iters / 10 sec<br>' +
+ '<b>SLOC</b>: ' + i.sloc + ' lines<br>' +
+ //'<b>Author</b>: <a href="' + i.author_url + '">' +
+ //i.author_name + '</a><br>' +
+ '<b>Author</b>: ' + i.author_name + '<br>' +
+ '</p>'
+ })
+ d3.json("all_data.json", function (error, data) {
+ allData = data
+ updateGraphData()
+ })
+ return chart
+})
+
--- /dev/null
+<html>
+<head>
+ <meta charset="utf-8">
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css" rel="stylesheet" type="text/css">
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js" charset="utf-8"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.js"></script>
+
+ <style>
+ text {
+ font: 12px sans-serif;
+ }
+ svg {
+ display: block;
+ }
+ .impl-data {
+ text-align: left !important;
+ }
+ #title {
+ text-align: center;
+ padding: 5px;
+ }
+ #mal {
+ height: 80%;
+ width: 100%;
+ }
+ html, body, #mal, svg {
+ margin: 0px;
+ padding: 0px;
+ }
+ </style>
+</head>
+<body class='with-3d-shadow with-transitions'>
+
+<div>
+ <h2 id="title">Mal Implementation Stats</h2>
+</div>
+
+<div>
+ <table border=0>
+ <tr>
+ <th align=right>Color data:</th>
+ <td>
+ <input type="radio" class="selects" name="ckey" value="syntax">Syntax Style
+ <input type="radio" class="selects" name="ckey" value="type_check">Type Discipline
+ <input type="radio" class="selects" name="ckey" value="author_name">Author
+ </td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr>
+ <th align=right>X-Axis data:</th>
+ <td>
+ <input type="radio" class="selects" name="xkey" value="perf1">Perf 1
+ <input type="radio" class="selects" name="xkey" value="perf2">Perf 2
+ <input type="radio" class="selects" name="xkey" value="perf3">Perf 3
+ <input type="radio" class="selects" name="xkey" value="rank">Popularity
+ <input type="radio" class="selects" name="xkey" value="sloc">SLOC size
+ <input type="radio" class="selects" name="xkey" value="files">File count
+ </td>
+ <td> </td>
+ <td><input type="checkbox" class="selects" name="xlog" value=true>Logarithmic</td>
+ </tr>
+ <tr>
+ <th align=right>Y-Axis data:</th>
+ <td>
+ <input type="radio" class="selects" name="ykey" value="perf1">Perf 1
+ <input type="radio" class="selects" name="ykey" value="perf2">Perf 2
+ <input type="radio" class="selects" name="ykey" value="perf3">Perf 3
+ <input type="radio" class="selects" name="ykey" value="rank">Popularity
+ <input type="radio" class="selects" name="ykey" value="sloc">SLOC size
+ <input type="radio" class="selects" name="ykey" value="files">File count
+ </td>
+ <td> </td>
+ <td><input type="checkbox" class="selects" name="ylog" value=true>Logarithmic</td>
+ </tr>
+ <tr>
+ <th align=right>Circle size:</th>
+ <td>
+ <input type="radio" class="selects" name="skey" value="perf1">Perf 1
+ <input type="radio" class="selects" name="skey" value="perf2">Perf 2
+ <input type="radio" class="selects" name="skey" value="perf3">Perf 3
+ <input type="radio" class="selects" name="skey" value="rank">Popularity
+ <input type="radio" class="selects" name="skey" value="sloc">SLOC size
+ <input type="radio" class="selects" name="skey" value="files">File count
+ </td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ </table>
+</div>
+
+<div id="mal" class="chartWrap">
+ <svg></svg>
+</div>
+
+<script src="graph_languages.js"></script>
+</body>
+
+</html>
--- /dev/null
+{
+ "name": "mal_graph",
+ "version": "0.0.1",
+ "description": "Graph Mal Languages",
+ "dependencies": {
+ "js-yaml": "3.12.2",
+ "request": "2.88.0",
+ "request-promise-native": "1.0.7"
+ }
+}