├── public
├── lib
├── jison
├── jison.js
├── style
│ ├── aescrawl.eot
│ ├── aescrawl.ttf
│ ├── aescrawl.woff
│ ├── sh_navy.min.css
│ ├── style.css
│ ├── sh_javascript.min.js
│ ├── sh_main.min.js
│ └── aescrawl.svg
├── demo.js
├── json2-min.js
└── index.html
├── .gitmodules
├── test.js
├── Jack.tmbundle
├── info.plist
├── Preferences
│ └── Comments.tmPreferences
└── Syntaxes
│ └── Jack.tmLanguage
├── Makefile
├── README.markdown
├── test.jack
├── control_flow.jack
├── data_types.jack
└── lib
├── jack.js
└── jack
├── grammar.js
├── generator.js
└── lexer.js
/public/lib:
--------------------------------------------------------------------------------
1 | ../lib
--------------------------------------------------------------------------------
/public/jison:
--------------------------------------------------------------------------------
1 | ../jison/lib/jison
--------------------------------------------------------------------------------
/public/jison.js:
--------------------------------------------------------------------------------
1 | ../jison/lib/jison.js
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "jison"]
2 | path = jison
3 | url = https://github.com/zaach/jison.git
4 |
--------------------------------------------------------------------------------
/public/style/aescrawl.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creationix/jack-old/HEAD/public/style/aescrawl.eot
--------------------------------------------------------------------------------
/public/style/aescrawl.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creationix/jack-old/HEAD/public/style/aescrawl.ttf
--------------------------------------------------------------------------------
/public/style/aescrawl.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/creationix/jack-old/HEAD/public/style/aescrawl.woff
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | require.paths.unshift(__dirname + "/lib");
2 | var Jack = require('jack').Jack;
3 | var Fs = require('fs');
4 |
5 | Fs.readFile('control_flow.jack', 'utf8', function (err, code) {
6 | console.log(Jack.compile(code));
7 | });
8 |
9 |
--------------------------------------------------------------------------------
/Jack.tmbundle/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Jack
7 | uuid
8 | CD464DB4-46C6-4631-9838-54B43C925D83
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: single
2 |
3 | single:
4 | echo "// jack/lexer.js\n" > public/jack.js
5 | cat lib/jack/lexer.js >> public/jack.js
6 | echo "\n// jack/grammar.js\n" >> public/jack.js
7 | cat lib/jack/grammar.js >> public/jack.js
8 | echo "\n// jack/generator.js\n" >> public/jack.js
9 | cat lib/jack/generator.js >> public/jack.js
10 | echo "\n// jack.js\n" >> public/jack.js
11 | cat lib/jack.js >> public/jack.js
12 |
13 | # Requires that compiler.jar be in the parent directory.
14 | # See google closure for details
15 | compressed: single
16 | java -jar ../compiler.jar --js public/jack.js -js_output_file public/jack-min.js
17 |
18 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # Jack - Making programming playful
2 |
3 | Jack is a new language in development that gets translated to pure JavaScript and runs on top of nodeJS.
4 |
5 | ## Ideals
6 |
7 | - Be Simple! This is very important
8 | - Be fun! Otherwise, what's the point
9 | - Be productive! We can only really make time for this is something good comes out of it.
10 |
11 | ## Technical ideas
12 |
13 | - Compile cleanly down to JavaScript.
14 | - Use real prototypical inheritance, not the hacked version that made it into JavaScript.
15 | - Use real whitespace rules and get rid of those semicolons and braces.
16 | - Create a clean syntax for defining variables, objects and functions/blocks. That should be all that's needed.
17 | - Not allow fuzzy things like implicit globals and type coercion.
18 | - Implement a real compiler with some static analysis, not just regular expression hacks.
19 | - Unit tests all the way!
20 |
21 | ## Sample
22 |
23 |
--------------------------------------------------------------------------------
/Jack.tmbundle/Preferences/Comments.tmPreferences:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | name
6 | Comments
7 | scope
8 | source.jack
9 | settings
10 |
11 | shellVariables
12 |
13 |
14 | name
15 | TM_COMMENT_START
16 | value
17 | #
18 |
19 |
20 | name
21 | TM_COMMENT_START_2
22 | value
23 | /*
24 |
25 |
26 | name
27 | TM_COMMENT_END_2
28 | value
29 | */
30 |
31 |
32 |
33 | uuid
34 | 47512F6D-BE9A-4B1D-BDBA-7F8C6A476AA9
35 |
36 |
37 |
--------------------------------------------------------------------------------
/test.jack:
--------------------------------------------------------------------------------
1 | # Assignment:
2 | number = 42
3 | opposite_day = true
4 |
5 | # Conditions:
6 | if opposite_day
7 | number = -42
8 | end
9 |
10 | # Functions:
11 | square = fun x -> /x * x/g
12 | curry = fun a -> fun b -> "$a + $b"
13 | # Arrays:
14 | list = [1, 2, 3, 4, 5]
15 |
16 | # Objects:
17 | math = {
18 | root = Math
19 | square = square
20 | cube = fun x -> true
21 | }
22 |
23 | # Heredoc
24 | message = '''
25 | Several lines
26 | that can be
27 | indented.
28 | '''
29 |
30 | # Block functions:
31 | race = fun winner, runners ->
32 | winner
33 | runners
34 | end
35 |
36 | # Inherited Objects
37 | Animal = {legs=4 eyes=2}
38 | Insect = {Animal legs=6}
39 | Enumerable = {Array
40 | each = fun -> "Not implemented"
41 | reduce = fun -> 'Not implemented'
42 | }
43 |
44 | # Inherited Arrays
45 | [Enumerable 1,2,3,4,5]
46 |
47 | # Interpolated Strings
48 | # Based on an idea from Google's caja project
49 | # http://bit.ly/4irVV1
50 | "Hello $name"
51 | HTML"""
52 |
53 |
54 | $title
55 |
56 |
57 | ...
58 |
59 |
60 | """
61 | JSON"{items: ${items.length}}"
62 |
63 |
--------------------------------------------------------------------------------
/control_flow.jack:
--------------------------------------------------------------------------------
1 | # Assignment
2 | language = "Jack"
3 | cool = ok
4 | Animal = {legs=4 eyes=2}
5 |
6 | # Loops over objects/arrays
7 | for key, value in myObj if true
8 | # ...
9 | end
10 | # Compiles to:
11 | #
12 | # var key, value;
13 | # for (key in myObj) {
14 | # if (myObj.hasOwnProperty(key) && true) {
15 | # value = myObj[key];
16 | # # ...
17 | # }
18 | # }
19 |
20 | # Array comprehensions
21 | [item for item in myList if item]
22 | # Compiles to:
23 | # myList.filter(function (item) {
24 | # return item;
25 | # }).map(function (item) {
26 | # return item;
27 | # });
28 |
29 | # Object comprehensions
30 | {value for key, value in myObj unless value.length < 2}
31 | # Compiles to:
32 | #
33 | # Object.comprehension(myObj, function(key, value) {
34 | # return value;
35 | # }, function (key, value) {
36 | # return key.length < 2
37 | # });
38 | #
39 | # OR:
40 | #
41 | # (function () {
42 | # var newobj = {}, key, value;
43 | # for (key in myObj) {
44 | # value = myObj[key];
45 | # if (myObj.hasOwnProperty(key) && !(key.length < 2)) {
46 | # newobj[key] = value;
47 | # }
48 | # }
49 | # return newobj;
50 | # }());
51 |
52 |
53 | # Long test
54 | long = {one=1 two=2 three=3 four=4 five=5 six=6 seven=7 eight=8 nine=9 ten=10}
55 | [
56 | [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
57 | [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
58 | [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
59 | ]
60 | [1,2,3,4,5]
61 |
62 | # Postfix conditionals
63 | do = ok if false
64 | do = no unless true
65 |
66 | # Conditionals
67 | if strange_stuff
68 | Octocat = {Animal legs=8}
69 | else
70 | Cat = {Animal}
71 | end
72 |
73 | # Inverse conditional
74 | unless opposite_day
75 | day = false
76 | end
77 |
78 | square = fun x ->
79 | x = true
80 | Cat = false
81 | newvar = no
82 | end
--------------------------------------------------------------------------------
/public/style/sh_navy.min.css:
--------------------------------------------------------------------------------
1 | pre.sh_sourceCode{background-color:#000035;color:#008bff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_keyword{color:#f8c50b;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_type{color:#e1e72f;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_string{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_regexp{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_specialchar{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_comment{color:#fb0;font-weight:normal;font-style:italic;}pre.sh_sourceCode .sh_number{color:#f87ff4;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_preproc{color:#b0f;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_symbol{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_function{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_cbracket{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_url{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_date{color:#f8c50b;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_time{color:#f8c50b;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_file{color:#f8c50b;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_ip{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_name{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_variable{color:#13d8ef;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_oldfile{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_newfile{color:#fff;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_difflines{color:#f8c50b;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_selector{color:#13d8ef;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_property{color:#f8c50b;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_value{color:#fff;font-weight:normal;font-style:normal;}
--------------------------------------------------------------------------------
/public/demo.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | var compile, onChange, output, real_compile, setOutput, source, status, timer;
3 | source = null;
4 | output = null;
5 | status = null;
6 | setOutput = function setOutput(js) {
7 | // Remove the contents
8 | while (output.firstChild) {
9 | output.removeChild(output.firstChild);
10 | }
11 | // put in new contents
12 | return output.appendChild(document.createTextNode(js));
13 | };
14 | real_compile = function real_compile() {
15 | var code, js;
16 | code = source.value;
17 | try {
18 | js = Jack.compile(code);
19 | setOutput(js);
20 | sh_highlightDocument();
21 | } catch (e) {
22 | setOutput(e.stack);
23 | }
24 | return status.style.display = "none";
25 | };
26 | // Called
27 | compile = function compile() {
28 | status.style.display = "block";
29 | return setTimeout(real_compile, 0);
30 | };
31 | // Recompile after 500ms of idle time after any activity.
32 | timer = null;
33 | onChange = function onChange(e) {
34 | if (timer) {
35 | clearTimeout(timer);
36 | }
37 | return timer = setTimeout(compile, 500);
38 | };
39 | // Wait for the dom to be built before moving on.
40 | this.onload = function onload() {
41 | var sample;
42 | // Store references to our textareas.
43 | source = document.getElementById("source");
44 | output = document.getElementById("output");
45 | status = document.getElementById("status");
46 | // Load the sample code out of the script tag in the head.
47 | sample = document.getElementById("sample").innerHTML;
48 | sample = sample.substr(1, sample.length);
49 | // Fill in the box with the input and call compile
50 | source.value = sample;
51 | compile();
52 | source.focus();
53 | // Bind onkeyup and onchange in the text field
54 | source.addEventListener('keyup', onChange, false);
55 | return source.addEventListener('change', onChange, false);
56 | };
57 | })();
58 |
--------------------------------------------------------------------------------
/data_types.jack:
--------------------------------------------------------------------------------
1 | # Boolean Literals
2 | # (Superset of JavaScript)
3 | true
4 | false
5 | on
6 | off
7 | yes
8 | no
9 |
10 | # Number Literals
11 | # (Same as JavaScript)
12 | 0xff0088
13 | 523
14 | 0XFFEE33
15 | 123.32
16 | -0.32
17 | 0.234
18 | 6.02e23
19 | 6.02E23
20 |
21 | # String Literals
22 | # Single quote only, but with heredoc style added
23 | # Heredoc contents don't include opening line and
24 | # are left trimmed to match closing triplet.
25 | 'Hello \'World\''
26 | '''
27 | Hello "World"
28 | In 'Multi' lines
29 | '''
30 |
31 | # Interpolated literals
32 | # Double quotes and double heredoc
33 | # Values are replaced last minute by a smart agent.
34 | # (SQL escaper, HTML escape)
35 | "Hello $planetoid"
36 | SQL"""
37 | SELECT * FROM users
38 | WHERE name = $name
39 | """
40 | HTML"$title"
41 |
42 | # http://google-caja.googlecode.com/svn/changes/mikesamuel/string-interpolation-29-Jan-2008/trunk/src/js/com/google/caja/interp/index.html
43 | # Interpolated use cases
44 | "$noun :verb"
45 | #-> String.interpolate(noun, " ", verb)
46 | #=> "World Greets"
47 |
48 | SQL"SELECT * FROM users WHERE name=$name"
49 | #-> SQL.interpolate("SELECT * FROM users WHERE name=", name)
50 | #=> "SELECT * FROM users WHERE name='O''Connor'"
51 |
52 | JSON"{name: ${data.name}, age: ${data.age}"
53 | #-> JSON.interpolate("{name: ", name, ", data.age: ", data.age}")
54 | #=> "{name: "Tim", age: 27}"
55 |
56 | # Regular Expression literals
57 | /123/g
58 | /^([^a-z]+)$/i
59 |
60 | # List Literals
61 | [ 1, 2, 3, 4 ]
62 | [
63 | 1,0,0
64 | 0,1,0
65 | 0,0,1
66 | ]
67 |
68 | # Object Literals
69 | {name="Tim" age=27}
70 | {
71 | name="Tim"
72 | age=27
73 | }
74 |
75 | # Delegated Objects
76 | # Creates a new object that inherits from the given
77 | # prototype, and then overrides some properties.
78 | {Animal name="George" color="Brown"}
79 | {Animal
80 | name="George"
81 | color="Brown"
82 | }
83 |
84 | # Delegated Lists
85 | # Creates a clone of the passed in List-like object
86 | # but replaces the contents with that given.
87 | [HTMLColors 0x000000, 0xff8800, 0x0088ff, 0x887788]
88 | [HTMLColors
89 | 0x000000
90 | 0xff8800
91 | 0x0088ff
92 | 0x887788
93 | ]
94 |
95 | # Function literal
96 | fun x -> true
97 | # Block Function
98 | fun x, y ->
99 | x
100 | y
101 | end
--------------------------------------------------------------------------------
/lib/jack.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var root = (typeof exports !== "undefined" && exports) || this,
3 | Jack = root.Jack || (root.Jack = {});
4 | Jack.tokenize || (Jack.tokenize = require('jack/lexer').Jack.tokenize);
5 | Jack.parse || (Jack.parse = require('jack/grammar').Jack.parse);
6 | Jack.generate || (Jack.generate = require('jack/generator').Jack.generate);
7 | Jack.compile = function (code) {
8 | var tokens, tree, js;
9 | try {
10 | tokens = Jack.tokenize(code);
11 | tree = Jack.parse(tokens);
12 | js = Jack.generate(tree);
13 | return js;
14 | } catch (e) {
15 | var message, num, token,
16 | before, after, token_before, token_after;
17 |
18 | // Split the jison error message.
19 | message = e.message.split("\n");
20 | num = parseInt(message[1]) - 1;
21 | message = message[0];
22 |
23 | if (tokens) {
24 | if (token = tokens[num]) {
25 | before = code.substr(0, token.offset).match(/\n?.*$/)[0];
26 | after = code.substr(token.offset, code.length).match(/^.*\n?/)[0];
27 | token_before = tokens.slice(0, num).filter(function (other_token) {
28 | return other_token.lineno == token.lineno;
29 | }).map(function (other_token) {
30 | return other_token.name;
31 | });
32 | token_after = tokens.slice(num).filter(function (other_token) {
33 | return other_token.lineno == token.lineno;
34 | }).map(function (other_token) {
35 | return other_token.name;
36 | });
37 | e.message = message +
38 | " but found '" + token.name + "'\n" +
39 | "Line " + token.lineno + ": " + JSON.stringify(before) + " !! " + JSON.stringify(after) + "'\n" +
40 | "Tokens " + JSON.stringify(token_before) + " !! " + JSON.stringify(token_after);
41 | }
42 | } else {
43 | before = code.substr(0, num).match(/\n?.*$/)[0];
44 | after = code.substr(num, code.length).match(/^.*\n?/)[0];
45 | line_no = code.substr(0, num).split("\n").length;
46 | e.message = message + "\n" +
47 | "Line " + line_no + ": " + JSON.stringify(before) + " !! " + JSON.stringify(after);
48 | }
49 | throw e;
50 | }
51 | };
52 |
53 | }());
54 | if (typeof window !== "undefined" && typeof exports !== "undefined") {
55 | window.Jack = exports.Jack;
56 | }
57 |
--------------------------------------------------------------------------------
/public/json2-min.js:
--------------------------------------------------------------------------------
1 | if(!this.JSON)this.JSON={};
2 | (function(){function k(a){return a<10?"0"+a:a}function n(a){o.lastIndex=0;return o.test(a)?'"'+a.replace(o,function(c){var d=q[c];return typeof d==="string"?d:"\\u"+("0000"+c.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function l(a,c){var d,f,i=g,e,b=c[a];if(b&&typeof b==="object"&&typeof b.toJSON==="function")b=b.toJSON(a);if(typeof j==="function")b=j.call(c,a,b);switch(typeof b){case "string":return n(b);case "number":return isFinite(b)?String(b):"null";case "boolean":case "null":return String(b);
3 | case "object":if(!b)return"null";g+=m;e=[];if(Object.prototype.toString.apply(b)==="[object Array]"){f=b.length;for(a=0;a|\|/g,"sh_symbol",-1],[/\{|\}/g,"sh_cbracket",-1],[/\b(?:Math|Infinity|NaN|undefined|arguments)\b/g,"sh_predef_var",-1],[/\b(?:Array|Boolean|Date|Error|EvalError|Function|Number|Object|RangeError|ReferenceError|RegExp|String|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt)\b/g,"sh_predef_func",-1],[/(?:[A-Za-z]|_)[A-Za-z0-9_]*(?=[ \t]*\()/g,"sh_function",-1]],[[/$/g,null,-2],[/(?:)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[//g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/-->/g,"sh_comment",-2],[/