4 | TypedJS
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/_site/examples/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TypedJS
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/node-cli.js:
--------------------------------------------------------------------------------
1 | var TypedJS = require('../typed');
2 | // typedjs_parser needs to be declared globally for now...
3 | typedjs_parser = require('../typedjs_parser');
4 |
5 |
6 | // Example function to test...
7 | function concat(a, b) {
8 | return a + b;
9 | }
10 |
11 | // You can manually add tests to TypedJS
12 | // The first parameter is the type signature
13 | // The second parameter is the actual function we'll be testing
14 | var test = TypedJS.addTest('concat :: String -> String -> String', concat);
15 |
16 | // Call 'go' to execute the automated tests
17 | // go requires one parameter and it's an Array of the tests to run.
18 | TypedJS.go([test]);
19 |
--------------------------------------------------------------------------------
/examples/node-file.js:
--------------------------------------------------------------------------------
1 | // This is a really dirty way to get TypedJS running via node.
2 |
3 | // You'll need to add typedjs_parser as a global for now.
4 | var TypedJS = require('../typed');
5 | typedjs_parser = require('../typedjs_parser');
6 |
7 | // A vm is necessary so you can bind all the global functions to 'window'
8 | var fs = require('fs');
9 | var vm = require('vm');
10 |
11 | // Extract the data from the file
12 | var fileData = fs.readFileSync('examples/test.js', 'utf-8');
13 |
14 | // Pull in all the global functions into window
15 | window = {};
16 | vm.runInNewContext(fileData, window);
17 |
18 |
19 | // Run TypedJS on the fileData String.
20 | // TypedJS will parse all your type signatures
21 | // read the functions from 'window' and execute
22 | // the automated tests.
23 | TypedJS.run_tests_on_string(fileData);
24 |
--------------------------------------------------------------------------------
/examples/test.js:
--------------------------------------------------------------------------------
1 |
2 | //+ add_all :: [Number] -> Number
3 |
4 | function add_all(num_arr){
5 | var count = num_arr[0]; // Error, could be nil
6 | for(i = 1; i < num_arr.length; i++){
7 | count = num_arr[i];
8 | }
9 | return count;
10 | };
11 |
12 | //+ my_prop :: {name:String, valid:Boolean} -> Boolean
13 |
14 | function my_prop(obj){
15 | if(obj.valid === true){
16 | return "true"; // Error, we are
17 | } // returning a string here
18 | else{
19 | return obj.valid;
20 | }
21 | };
22 |
23 | //+ fullname :: {first:String, last:String} -> String
24 | function fullname(obj){
25 | return obj.first + " " + obj.last;
26 | }
27 |
28 | //+ join_char :: String -> String -> String
29 | function join_char(c1,c2){
30 | return c1;
31 | }
32 |
33 | //+ test_obj :: {name:String, email:String} -> {name:String, email:String}
34 | function test_obj(o){
35 | return o;
36 | }
37 |
38 | //+ test_or :: {name:String, email:String} -> {name:String, email:String} | Boolean
39 | function test_or(o){
40 | if(Math.round(Math.random())===0){
41 | return {name:"Etan",email:"ok"};
42 | }
43 | else{
44 | return true; //true;
45 | }
46 | };
47 |
48 | //+ test_arr :: String | Number -> String -> [String | Number]
49 | function test_arr(s1,s2){
50 | return [s1,s2];
51 | }
52 |
53 | MyObj = {
54 | //+ MyObj.test_fun :: Number -> Number -> Number
55 | test_fun:function(num1, num2){
56 | return num1 + num2;
57 | }
58 | }
59 |
60 | //+ add_tos :: Number -> Number -> String
61 |
62 | function add_tos(n1,n2){
63 | return (n1 + n2) + "";
64 | }
--------------------------------------------------------------------------------
/_site/examples/test.js:
--------------------------------------------------------------------------------
1 |
2 | //+ add_all :: [Number] -> Number
3 |
4 | function add_all(num_arr){
5 | var count = num_arr[0]; // Error, could be nil
6 | for(i = 1; i < num_arr.length; i++){
7 | count = num_arr[i];
8 | }
9 | return count;
10 | };
11 |
12 | //+ my_prop :: {name:String, valid:Boolean} -> Boolean
13 |
14 | function my_prop(obj){
15 | if(obj.valid === true){
16 | return "true"; // Error, we are
17 | } // returning a string here
18 | else{
19 | return obj.valid;
20 | }
21 | };
22 |
23 | //+ fullname :: {first:String, last:String} -> String
24 | function fullname(obj){
25 | return obj.first + " " + obj.last;
26 | }
27 |
28 | //+ join_char :: String -> String -> String
29 | function join_char(c1,c2){
30 | return c1;
31 | }
32 |
33 | //+ test_obj :: {name:String, email:String} -> {name:String, email:String}
34 | function test_obj(o){
35 | return o;
36 | }
37 |
38 | //+ test_or :: {name:String, email:String} -> {name:String, email:String} | Boolean
39 | function test_or(o){
40 | if(Math.round(Math.random())===0){
41 | return {name:"Etan",email:"ok"};
42 | }
43 | else{
44 | return true; //true;
45 | }
46 | };
47 |
48 | //+ test_arr :: String | Number -> String -> [String | Number]
49 | function test_arr(s1,s2){
50 | return [s1,s2];
51 | }
52 |
53 | MyObj = {
54 | //+ MyObj.test_fun :: Number -> Number -> Number
55 | test_fun:function(num1, num2){
56 | return num1 + num2;
57 | }
58 | }
59 |
60 | //+ add_tos :: Number -> Number -> String
61 |
62 | function add_tos(n1,n2){
63 | return (n1 + n2) + "";
64 | }
--------------------------------------------------------------------------------
/_site/Readme.markdown:
--------------------------------------------------------------------------------
1 | ## TypedJS
2 |
3 | Basic, automatic JavaScript testing. Requires jQuery. This is just a start. TypedJS will soon provide more complex forms of program specification, and analysis. The goal: safe, correct JavaScript.
4 |
5 | (Warning: In need of some refactoring).
6 |
7 | ### Usage
8 |
9 | First, annotate your javascript functions with Haskell-like type signatures:
10 |
11 | //+ char_first :: Char -> Char -> Char
12 |
13 | function char_first(c1,c2){
14 | return c1;
15 | }
16 |
17 | //+ my_prop :: {name:String, valid:Boolean} -> Boolean
18 |
19 | function my_prop(obj){
20 | if(obj.valid === true){
21 | return "true"; // Error, we are
22 | } // returning a string here
23 | else{
24 | return obj.valid;
25 | }
26 | };
27 |
28 | // We can do objects, too:
29 |
30 | MyObj = {
31 | //+ MyObj.test_fun :: Number -> Number -> Number
32 | test_fun:function(num1, num2){
33 | return num1 + num2;
34 | }
35 | }
36 |
37 | Then load your JavaScript file in a browser window and run:
38 |
39 | TypedJS.run_tests()
40 |
41 | If you want to instrument your annotated functions to dynamically detect type violations, run:
42 |
43 | TypedJS.run_tests(true)
44 |
45 | ### Types
46 |
47 | Currently available primitives:
48 |
49 | Number
50 | String
51 | Boolean
52 |
53 | And "ORs" of primitives:
54 |
55 | Number | String // Number or String
56 | Boolean | Number // Boolean or Number
57 | ...
58 |
59 | And tuples (T1, T2, ... TN) E.g:
60 |
61 | (Number, String, Boolean, Boolean) // An example instance => [4,"hello",true,true]
62 | (Boolean, Boolean) // An example instance => [true, false]
63 |
64 | And arrays:
65 |
66 | [Number] // Array of number
67 | [Number | String] // Array of numbers or strings
68 |
69 | And objects, which can be nested and mixed with other types E.g:
70 |
71 | {key1: String, key2:[Number], key3:{subkey1:String, subkey2: Number}}
72 |
73 |
74 |
75 |
76 |
77 | ### License
78 |
79 | Attribution-NonCommercial 3.0 Unported (CC BY-NC 3.0)
80 |
--------------------------------------------------------------------------------
/typedjs_parser.jison:
--------------------------------------------------------------------------------
1 |
2 | /* lexical grammar */
3 | %lex
4 | %%
5 |
6 | \s+ /* skip whitespace */
7 | "String" return 'string'
8 | "Number" return 'number'
9 | "Char" return 'char'
10 | "Boolean" return 'boolean'
11 | ([a-z]|[A-Z]|\_|\.)+ return 'VAR'
12 | "//+" return 'BEGIN'
13 | "," return ','
14 | "(" return '('
15 | ")" return ')'
16 | "[" return '['
17 | "]" return ']'
18 | "{" return '{'
19 | "}" return '}'
20 | "::" return '::'
21 | "->" return '->'
22 | ":" return ':'
23 | "|" return '|'
24 | <> return 'EOF'
25 | . return 'INVALID'
26 |
27 | /lex
28 |
29 | /* operator associations and precedence */
30 |
31 | %left ','
32 | %left ':'
33 | %left '|'
34 |
35 |
36 | %start expressions
37 |
38 | %% /* language grammar */
39 |
40 | expressions
41 | : BEGIN VAR "::" arg_list EOF
42 | {return '{"func":"' + $2 + '","args":[' +$4 + ']}';}
43 | ;
44 |
45 | arg_list
46 | : e
47 | {$$ = $1;}
48 | | arg_list "->" e
49 | {$$ = $1 +"," + $3;}
50 | ;
51 |
52 | primitive
53 | : string
54 | {$$ = '"string"';}
55 | | char
56 | {$$ = '"char"';}
57 | | number
58 | {$$ = '"number"';}
59 | | boolean
60 | {$$ = '"boolean"';}
61 | ;
62 |
63 | tuple
64 | : '(' e ')'
65 | {$$ = "["+$2+"]";}
66 | ;
67 |
68 | object
69 | : '{' e '}'
70 | {$$ = "{"+$2+"}";}
71 | ;
72 |
73 | list
74 | : '[' primitive ']'
75 | {$$ = '{"array":' + $2 + '}';}
76 | | '[' object ']'
77 | {$$ = '{"array":' + $2 + '}';}
78 | | '[' tuple ']'
79 | {$$ = '{"array":' + $2 + '}';}
80 | | '[' list ']'
81 | {$$ = '{"array":' + $2 + '}';}
82 | | '[' or ']'
83 | {$$ = '{"array":{"or":[' + $2 + ']}}'; }
84 | ;
85 |
86 | or
87 | : e '|' e
88 | {$$ = $1 + ',' + $3;}
89 | ;
90 |
91 | e
92 | : e ',' e
93 | {$$ = $1+','+$3;}
94 | | or
95 | {$$ = '{"or":[' + $1 + ']}';}
96 | | object
97 | | tuple
98 | | list
99 | | primitive
100 | | e ':' e
101 | {$$ = $1 +':'+ $3;}
102 | | VAR
103 | {$$ = '"' + String(yytext) + '"';}
104 | ;
--------------------------------------------------------------------------------
/_site/typedjs_parser.jison:
--------------------------------------------------------------------------------
1 |
2 | /* lexical grammar */
3 | %lex
4 | %%
5 |
6 | \s+ /* skip whitespace */
7 | "String" return 'string'
8 | "Number" return 'number'
9 | "Char" return 'char'
10 | "Boolean" return 'boolean'
11 | ([a-z]|[A-Z]|\_|\.)+ return 'VAR'
12 | "//+" return 'BEGIN'
13 | "," return ','
14 | "(" return '('
15 | ")" return ')'
16 | "[" return '['
17 | "]" return ']'
18 | "{" return '{'
19 | "}" return '}'
20 | "::" return '::'
21 | "->" return '->'
22 | ":" return ':'
23 | "|" return '|'
24 | <> return 'EOF'
25 | . return 'INVALID'
26 |
27 | /lex
28 |
29 | /* operator associations and precedence */
30 |
31 | %left ','
32 | %left ':'
33 | %left '|'
34 |
35 |
36 | %start expressions
37 |
38 | %% /* language grammar */
39 |
40 | expressions
41 | : BEGIN VAR "::" arg_list EOF
42 | {return '{"func":"' + $2 + '","args":[' +$4 + ']}';}
43 | ;
44 |
45 | arg_list
46 | : e
47 | {$$ = $1;}
48 | | arg_list "->" e
49 | {$$ = $1 +"," + $3;}
50 | ;
51 |
52 | primitive
53 | : string
54 | {$$ = '"string"';}
55 | | char
56 | {$$ = '"char"';}
57 | | number
58 | {$$ = '"number"';}
59 | | boolean
60 | {$$ = '"boolean"';}
61 | ;
62 |
63 | tuple
64 | : '(' e ')'
65 | {$$ = "["+$2+"]";}
66 | ;
67 |
68 | object
69 | : '{' e '}'
70 | {$$ = "{"+$2+"}";}
71 | ;
72 |
73 | list
74 | : '[' primitive ']'
75 | {$$ = '{"array":' + $2 + '}';}
76 | | '[' object ']'
77 | {$$ = '{"array":' + $2 + '}';}
78 | | '[' tuple ']'
79 | {$$ = '{"array":' + $2 + '}';}
80 | | '[' list ']'
81 | {$$ = '{"array":' + $2 + '}';}
82 | | '[' or ']'
83 | {$$ = '{"array":{"or":[' + $2 + ']}}'; }
84 | ;
85 |
86 | or
87 | : e '|' e
88 | {$$ = $1 + ',' + $3;}
89 | ;
90 |
91 | e
92 | : e ',' e
93 | {$$ = $1+','+$3;}
94 | | or
95 | {$$ = '{"or":[' + $1 + ']}';}
96 | | object
97 | | tuple
98 | | list
99 | | primitive
100 | | e ':' e
101 | {$$ = $1 +':'+ $3;}
102 | | VAR
103 | {$$ = '"' + String(yytext) + '"';}
104 | ;
--------------------------------------------------------------------------------
/Readme.markdown:
--------------------------------------------------------------------------------
1 | ## TypedJS
2 |
3 | Basic, automatic JavaScript testing. This is just a start. TypedJS will soon provide more complex forms of program specification, and analysis. The goal: safe, correct JavaScript.
4 |
5 | (Warning: In need of some refactoring).
6 |
7 | ### Usage
8 |
9 | First, annotate your javascript functions with Haskell-like type signatures:
10 |
11 | //+ str_first :: String -> String -> String
12 |
13 | function str_first(c1,c2){
14 | return c1;
15 | }
16 |
17 | //+ my_prop :: {name:String, valid:Boolean} -> Boolean
18 |
19 | function my_prop(obj){
20 | if(obj.valid === true){
21 | return "true"; // Error, we are
22 | } // returning a string here
23 | else{
24 | return obj.valid;
25 | }
26 | };
27 |
28 | // We can do objects, too:
29 |
30 | MyObj = {
31 | //+ MyObj.test_fun :: Number -> Number -> Number
32 | test_fun:function(num1, num2){
33 | return num1 + num2;
34 | }
35 | }
36 |
37 | #### Run in the Browser
38 |
39 | Load your JavaScript file in a browser window and run:
40 |
41 | TypedJS.run_tests()
42 |
43 | If you want to instrument your annotated functions to dynamically detect type violations, run:
44 |
45 | TypedJS.run_tests(true)
46 |
47 | #### Node.js support
48 |
49 | Add tests manually:
50 |
51 | var TypedJS = require('../typed');
52 | typedjs_parser = require('../typedjs_parser');
53 |
54 |
55 | // Example function to test...
56 | function concat(a, b) {
57 | return a + b;
58 | }
59 |
60 | // You can manually add tests to TypedJS
61 | // The first parameter is the type signature
62 | // The second parameter is the actual function we'll be testing
63 | var test = TypedJS.addTest('concat :: String -> String -> String', concat);
64 |
65 | // Call 'go' to execute the automated tests
66 | // go requires one parameter and it's an Array of the tests to run.
67 | TypedJS.go([test]);
68 |
69 | Or load a file:
70 |
71 |
72 | var TypedJS = require('../typed');
73 | typedjs_parser = require('../typedjs_parser');
74 |
75 | // A vm is necessary so you can bind all the global functions to 'window'
76 | var fs = require('fs');
77 | var vm = require('vm');
78 |
79 | // Extract the data from the file
80 | var fileData = fs.readFileSync('examples/test.js', 'utf-8');
81 |
82 | // Pull in all the global functions into window
83 | window = {};
84 | vm.runInNewContext(fileData, window);
85 |
86 |
87 | // Run TypedJS on the fileData String.
88 | // TypedJS will parse all your type signatures
89 | // read the functions from 'window' and execute
90 | // the automated tests.
91 | TypedJS.run_tests_on_string(fileData);
92 |
93 | ### Types
94 |
95 | Currently available primitives:
96 |
97 | Number
98 | String
99 | Boolean
100 |
101 | And ORs of primitives:
102 |
103 | Number | String // Number or String
104 | Boolean | Number // Boolean or Number
105 | ...
106 |
107 | And tuples (T1, T2, ... TN). For instance:
108 |
109 | (Number, String, Boolean, Boolean) // An example instance => [4,"hello",true,true]
110 | (Boolean, Boolean) // An example instance => [true, false]
111 |
112 | And arrays:
113 |
114 | [Number] // Array of Numbers. Example instances => [3,4,5] or [45,62,34,78,23]
115 | [Number | String] // Array of Numbers or Strings. Example instance => [3,"s",5,6,"h"]
116 |
117 | And objects, which can be nested and mixed with other types. For instance:
118 |
119 | {key1: String, key2:[Number], key3:{subkey1:String, subkey2: Number}}
120 |
121 | ### MIT License
122 |
123 | Copyright (C) 2012 Ethan Fast & Taazr Corporation
124 |
125 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
126 |
127 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
128 |
129 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
130 |
--------------------------------------------------------------------------------
/_site/typed.js:
--------------------------------------------------------------------------------
1 | var TypedJS = {
2 | possible:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`1234567890-=~!@#$%^&*()_+[]\{}|;':\",./<>?",
3 | test_cases:300,
4 | random_array_max_length:10,
5 | typeOf:function(o){
6 | var type = typeof o;
7 | if (type !== 'object'){
8 | return type;
9 | }
10 | else if (Object.prototype.toString.call(o) === '[object Array]'){
11 | return 'array';
12 | }
13 | else if (o === null){
14 | return 'null';
15 | }
16 | else {
17 | return 'object';
18 | }
19 | },
20 | gen_string:function(len){
21 | var text = "";
22 | for( var i=0; i < len; i++ )
23 | text += TypedJS.possible.charAt(Math.floor(Math.random() * TypedJS.possible.length));
24 | return text;
25 | },
26 | gen_char:function(){
27 | return TypedJS.gen_string(1).charAt(0);
28 | },
29 | gen_input_primative:function(obj){
30 | if (typeof(obj) === "string"){
31 | switch (obj){
32 | case "number":
33 | return Math.round(Math.random()*100);
34 | case "string":
35 | return TypedJS.gen_string(10);
36 | case "boolean":
37 | if(Math.random()*10 < 5)
38 | return true;
39 | else
40 | return false;
41 | case "char":
42 | return TypedJS.gen_char();
43 | default:
44 | return obj;
45 | }
46 | }
47 | else{
48 | throw "Bad Input Type: "+TypedJS.typeOf(obj)+" -- this shouldn't happen.";
49 | }
50 | },
51 | walk_object:function(obj){
52 | if(typeof(obj) === "object"){
53 | if(obj["array"] != undefined){
54 | var x = obj["array"], new_part = [],
55 | ran = Math.random()*TypedJS.random_array_max_length;
56 | for (var i = 1; i < ran; i++){
57 | new_part.push(TypedJS.walk_object(x));
58 | }
59 | return new_part;
60 | }
61 | else if(obj["or"] != undefined){
62 | var x = obj["or"], select = Math.floor(obj["or"].length * Math.random());
63 | return TypedJS.walk_object(obj["or"][select]);
64 | }
65 | else{
66 | var new_o;
67 | if (TypedJS.typeOf(obj) === "array") new_o = [];
68 | else new_o = {};
69 | for (i in obj){
70 | new_o[i] = TypedJS.walk_object(obj[i]);
71 | }
72 | return new_o;
73 | }
74 | }
75 | else{
76 | return TypedJS.gen_input_primative(obj);
77 | }
78 | },
79 | check_type:function(obj,exp){
80 | if(exp === undefined || obj === undefined){
81 | return false;
82 | }
83 | if(exp["or"] != undefined){
84 | var tmp = false;
85 | for(i in exp["or"]){
86 | tmp = tmp || TypedJS.check_type(obj, exp["or"][i]);
87 | }
88 | return tmp;
89 | }
90 | else{
91 | var top = TypedJS.typeOf(obj);
92 | if(top === "array"){
93 | if(TypedJS.typeOf(exp) === "array"){
94 | var tmp = true;
95 | for(var i = 0; i < obj.length; i++){
96 | tmp = tmp && TypedJS.check_type(obj[i], exp[i])
97 | }
98 | return tmp;
99 | }
100 | else if(exp["array"] != undefined){
101 | var tmp = true;
102 | for(var i = 0; i < obj.length; i++){
103 | tmp = tmp && TypedJS.check_type(obj[i], exp["array"])
104 | }
105 | return tmp;
106 | }
107 | else{
108 | return false;
109 | }
110 | }
111 | else if(top === "object"){
112 | var tmp = true;
113 | for(i in obj){
114 | tmp = tmp && TypedJS.check_type(obj[i],exp[i]);
115 | }
116 | return tmp;
117 | }
118 | else{
119 | return top === exp;
120 | }
121 | }
122 | },
123 | run_test:function(object,func,exp_typ,func_name,redefine){
124 | var fail_count = 0;
125 | for( var i = 0; i < TypedJS.test_cases; i++){
126 | var happy_sig = TypedJS.walk_object(object);
127 | try{
128 | var res = func.apply(this,(happy_sig));
129 | if(!redefine){
130 | if(!TypedJS.check_type(res,exp_typ)){
131 | throw "Type Error: " + func_name + ": " + "Expected " + JSON.stringify(exp_typ) + " but returned " + JSON.stringify(res) + " on input: " + JSON.stringify(happy_sig);
132 | }
133 | }
134 | }
135 | catch(e){
136 | console.log(e);
137 | fail_count = fail_count + 1;
138 | }
139 | }
140 | return fail_count;
141 | },
142 | go:function(testcases,redefine){
143 | var fail_count = 0;
144 | var func_fail = [], func_pass = [];
145 | if(testcases && testcases.length > 0){
146 | var total_cases = testcases.length * TypedJS.test_cases;
147 | for(var i in testcases){
148 | var test = testcases[i];
149 | var testcase = TypedJS.run_test(test.args, test.func, test.ret, test.func_name, redefine);
150 | fail_count = fail_count + testcase;
151 | if(testcase > 0){
152 | func_fail.push(test.func_name);
153 | }
154 | else{
155 | func_pass.push(test.func_name);
156 | }
157 | }
158 | console.log("Ran " + total_cases + " cases. Failed " + fail_count + ".");
159 | console.log("Functions which failed >1 test case: " + JSON.stringify(func_fail));
160 | }
161 | else{
162 | console.log("Please define TypedJS.test.");
163 | }
164 | return [func_fail,func_pass];
165 | },
166 | run_tests_on_string:function(str,redefine,json){
167 | var types = [],
168 | lines = str.split("\n");
169 | for(var i = 0; i < lines.length; i++){
170 | if(lines[i].replace(" ",'').replace(' ','').indexOf("//+") == 0){
171 | types.push(lines[i]);
172 | }
173 | }
174 | if(types.length > 0){
175 | var suite = [];
176 | for(var i = 0; i < types.length; i++){
177 | var base = JSON.parse(typedjs_parser.parse(types[i]));
178 | base["func_name"] = base["func"];
179 | base["ret"] = base["args"].splice(base["args"].length - 1, 1)[0];
180 | if(redefine) TypedJS.redefine(base["func_name"],base["args"],base["ret"]);
181 | base["func"] = TypedJS.comp_func(base["func"]);
182 | suite.push(base);
183 | }
184 | return TypedJS.go(suite, redefine);
185 | }
186 | },
187 | comp_func:function(func){
188 | var pieces = func.split(".");
189 | var curr_obj;
190 | for(var i = 0; i < pieces.length; i++){
191 | if(i === 0){
192 | curr_obj = window[pieces[0]];
193 | }
194 | else curr_obj = curr_obj[pieces[i]]
195 | }
196 | curr_obj.name = func;
197 | return curr_obj;
198 | },
199 | run_tests:function(redefine){
200 | if(redefine === undefined){
201 | redefine = false;
202 | }
203 | var scripts = $('script');
204 | scripts.each(function(i,el){
205 | $.get(el.src, function(data){
206 | TypedJS.run_tests_on_string(data,redefine);
207 | });
208 | });
209 | },
210 | // Checking types at runtime
211 | redefine:function(f_name, arg_types, ret_type){
212 | function wrap(f){
213 | return function(){
214 | try{
215 | if(arg_types != undefined){
216 | for(i in arguments){
217 | if(!TypedJS.check_type(arguments[i],arg_types[i])){
218 | throw "Type Error: Expected " + arg_types[i] + " but given " + JSON.stringify(arguments[i]);
219 | }
220 | }
221 | }
222 | if(ret_type != undefined){
223 | var ret = f.apply(this, arguments);
224 | if(!TypedJS.check_type(ret,ret_type)){
225 | throw "Type Error: " + f_name + ": Expected " + JSON.stringify(ret_type) + " but returned " + JSON.stringify(ret) + " on input args: " + JSON.stringify(arguments);
226 | }
227 | return ret;
228 | }
229 | return f.apply(this, arguments);
230 | }
231 | catch(e){
232 | console.log(e); // Do something more interesting here...
233 | throw e;
234 | }
235 | }
236 | };
237 | if(window[f_name] === undefined){
238 | var parts = f_name.split('.');
239 | var e_str = "window";
240 | for(i in parts){
241 | e_str = e_str + "[\"" + parts[i] + "\"]";
242 | }
243 | console.log(e_str);
244 | if(eval(e_str) === undefined){
245 | throw "Function " + f_name + " does not exist."
246 | }
247 | else{
248 | console.log("wrapping...");
249 | console.log(arg_types);
250 | e_str = e_str + "=wrap("+e_str+")";
251 | console.log(e_str);
252 | return eval(e_str);
253 | }
254 | }
255 | else{
256 | window[f_name] = wrap(window[f_name]);
257 | return window[f_name];
258 | }
259 | }
260 | }
261 |
262 |
263 |
264 |
--------------------------------------------------------------------------------
/typed.js:
--------------------------------------------------------------------------------
1 | var TypedJS = {
2 | possible:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`1234567890-=~!@#$%^&*()_+[]\{}|;':\",./<>?",
3 | test_cases:300,
4 | random_array_max_length:10,
5 | quiet: false,
6 | log: function () {
7 | this.quiet || (console.log(Array.prototype.slice.call(arguments, 0).join(' ')));
8 | },
9 | isArray:function(arr) {
10 | if (typeof Array.isArray === 'function') {
11 | return Array.isArray(arr);
12 | } else {
13 | return Object.prototype.toString.call(arr) === '[object Array]';
14 | }
15 | },
16 | typeOf:function(o){
17 | var type = typeof o;
18 | if (type !== 'object'){
19 | return type;
20 | }
21 | else if (this.isArray(o)) {
22 | return 'array';
23 | }
24 | else if (o === null){
25 | return 'null';
26 | }
27 | else {
28 | return 'object';
29 | }
30 | },
31 | gen_string:function(len){
32 | var text = "";
33 | for( var i=0; i < len; i++ )
34 | text += TypedJS.possible.charAt(Math.floor(Math.random() * TypedJS.possible.length));
35 | return text;
36 | },
37 | gen_char:function(){
38 | return TypedJS.gen_string(1).charAt(0);
39 | },
40 | gen_input_primative:function(obj){
41 | if (typeof(obj) === "string"){
42 | switch (obj){
43 | case "number":
44 | return Math.round(Math.random()*100);
45 | case "string":
46 | return TypedJS.gen_string(10);
47 | case "boolean":
48 | if(Math.random()*10 < 5)
49 | return true;
50 | else
51 | return false;
52 | case "char":
53 | return TypedJS.gen_char();
54 | default:
55 | return obj;
56 | }
57 | }
58 | else{
59 | throw "Bad Input Type: "+TypedJS.typeOf(obj)+" -- this shouldn't happen.";
60 | }
61 | },
62 | walk_object:function(obj){
63 | if(typeof(obj) === "object"){
64 | if(obj["array"] != undefined){
65 | var x = obj["array"], new_part = [],
66 | ran = Math.random()*TypedJS.random_array_max_length;
67 | for (var i = 1; i < ran; i++){
68 | new_part.push(TypedJS.walk_object(x));
69 | }
70 | return new_part;
71 | }
72 | else if(obj["or"] != undefined){
73 | var x = obj["or"], select = Math.floor(obj["or"].length * Math.random());
74 | return TypedJS.walk_object(obj["or"][select]);
75 | }
76 | else{
77 | var new_o;
78 | if (TypedJS.typeOf(obj) === "array") new_o = [];
79 | else new_o = {};
80 | for (i in obj){
81 | new_o[i] = TypedJS.walk_object(obj[i]);
82 | }
83 | return new_o;
84 | }
85 | }
86 | else{
87 | return TypedJS.gen_input_primative(obj);
88 | }
89 | },
90 | check_type:function(obj,exp){
91 | if(exp === undefined || obj === undefined){
92 | return false;
93 | }
94 | if(exp["or"] != undefined){
95 | var tmp = false;
96 | for(i in exp["or"]){
97 | tmp = tmp || TypedJS.check_type(obj, exp["or"][i]);
98 | }
99 | return tmp;
100 | }
101 | else{
102 | var top = TypedJS.typeOf(obj);
103 | if(top === "array"){
104 | if(TypedJS.typeOf(exp) === "array"){
105 | var tmp = true;
106 | for(var i = 0; i < obj.length; i++){
107 | tmp = tmp && TypedJS.check_type(obj[i], exp[i])
108 | }
109 | return tmp;
110 | }
111 | else if(exp["array"] != undefined){
112 | var tmp = true;
113 | for(var i = 0; i < obj.length; i++){
114 | tmp = tmp && TypedJS.check_type(obj[i], exp["array"])
115 | }
116 | return tmp;
117 | }
118 | else{
119 | return false;
120 | }
121 | }
122 | else if(top === "object"){
123 | var tmp = true;
124 | for(i in obj){
125 | tmp = tmp && TypedJS.check_type(obj[i],exp[i]);
126 | }
127 | return tmp;
128 | }
129 | else{
130 | return top === exp;
131 | }
132 | }
133 | },
134 | run_test:function(object,func,exp_typ,func_name,redefine){
135 | var fail_count = 0;
136 | for( var i = 0; i < TypedJS.test_cases; i++){
137 | var happy_sig = TypedJS.walk_object(object);
138 | try{
139 | var res = func.apply(this,(happy_sig));
140 | if(!redefine){
141 | if(!TypedJS.check_type(res,exp_typ)){
142 | throw "Type Error: " + func_name + ": " + "Expected " + JSON.stringify(exp_typ) + " but returned " + JSON.stringify(res) + " on input: " + JSON.stringify(happy_sig);
143 | }
144 | }
145 | }
146 | catch(e){
147 | TypedJS.log(e);
148 | fail_count = fail_count + 1;
149 | }
150 | }
151 | return fail_count;
152 | },
153 | go:function(testcases,redefine){
154 | var fail_count = 0;
155 | var func_fail = [], func_pass = [];
156 | if(testcases && testcases.length > 0){
157 | var total_cases = testcases.length * TypedJS.test_cases;
158 | for(var i in testcases){
159 | var test = testcases[i];
160 | var testcase = TypedJS.run_test(test.args, test.func, test.ret, test.func_name, redefine);
161 | fail_count = fail_count + testcase;
162 | if(testcase > 0){
163 | func_fail.push(test.func_name);
164 | }
165 | else{
166 | func_pass.push(test.func_name);
167 | }
168 | }
169 | TypedJS.log("Ran " + total_cases + " cases. Failed " + fail_count + ".");
170 | TypedJS.log("Functions which failed >1 test case: " + JSON.stringify(func_fail));
171 | }
172 | else{
173 | TypedJS.log("Please define TypedJS.test.");
174 | }
175 | return [func_fail,func_pass];
176 | },
177 | addTest: function (signature, fn, redefine) {
178 | if (signature.indexOf('//+') === -1) {
179 | signature = '//+' + signature;
180 | }
181 |
182 | var base = JSON.parse(typedjs_parser.parse(signature));
183 | base["func_name"] = base["func"];
184 | base["ret"] = base["args"].splice(base["args"].length - 1, 1)[0];
185 | if (redefine) TypedJS.redefine(base["func_name"],base["args"],base["ret"]);
186 | base["func"] = fn || this.comp_func(base["func"]);
187 | return base;
188 | },
189 | run_tests_on_string:function(str,redefine,json){
190 | var types = [],
191 | lines = str.split("\n");
192 | for(var i = 0; i < lines.length; i++){
193 | if(lines[i].replace(" ",'').replace(' ','').indexOf("//+") == 0){
194 | types.push(lines[i]);
195 | }
196 | }
197 | if(types.length > 0){
198 | var suite = [];
199 | for(var i = 0; i < types.length; i++) {
200 | var base = this.addTest(types[i], null, redefine);
201 | suite.push(base);
202 | }
203 | return TypedJS.go(suite, redefine);
204 | } else {
205 | return [[],[]];
206 | }
207 | },
208 | comp_func:function(func){
209 | var pieces = func.split(".");
210 | var curr_obj;
211 | for(var i = 0; i < pieces.length; i++){
212 | if(i === 0){
213 | curr_obj = window[pieces[0]];
214 | }
215 | else curr_obj = curr_obj[pieces[i]]
216 | }
217 | curr_obj.name = func;
218 | return curr_obj;
219 | },
220 | run_tests:function(redefine){
221 | if (redefine === undefined) {
222 | redefine = false;
223 | }
224 |
225 | function request(url, cb) {
226 | var httpRequest;
227 | if (window.XMLHttpRequest) {
228 | httpRequest = new XMLHttpRequest();
229 | } else if (window.ActiveXObject) {
230 | httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
231 | }
232 |
233 | httpRequest.onreadystatechange = function requestReadyState() {
234 | if (httpRequest.readyState === 4) {
235 | cb(httpRequest.responseText);
236 | }
237 | };
238 |
239 | httpRequest.open('GET', url, true);
240 | httpRequest.send(null);
241 | }
242 |
243 | var scripts = Array.prototype.slice.call(document.getElementsByTagName('script'), 0);
244 |
245 | for (var i = 0; i < scripts.length; i += 1) {
246 | request(scripts[i].src, function (data) {
247 | TypedJS.run_tests_on_string(data, redefine);
248 | });
249 | }
250 | },
251 | // Checking types at runtime
252 | redefine:function(f_name, arg_types, ret_type){
253 | function wrap(f){
254 | return function(){
255 | try{
256 | if(arg_types != undefined){
257 | for(i in arguments){
258 | if(!TypedJS.check_type(arguments[i],arg_types[i])){
259 | throw "Type Error: Expected " + arg_types[i] + " but given " + JSON.stringify(arguments[i]);
260 | }
261 | }
262 | }
263 | if(ret_type != undefined){
264 | var ret = f.apply(this, arguments);
265 | if(!TypedJS.check_type(ret,ret_type)){
266 | throw "Type Error: " + f_name + ": Expected " + JSON.stringify(ret_type) + " but returned " + JSON.stringify(ret) + " on input args: " + JSON.stringify(arguments);
267 | }
268 | return ret;
269 | }
270 | return f.apply(this, arguments);
271 | }
272 | catch(e){
273 | TypedJS.log(e); // Do something more interesting here...
274 | throw e;
275 | }
276 | }
277 | };
278 | if(window[f_name] === undefined){
279 | var parts = f_name.split('.');
280 | var e_str = "window";
281 | for(i in parts){
282 | e_str = e_str + "[\"" + parts[i] + "\"]";
283 | }
284 | TypedJS.log(e_str);
285 | if(eval(e_str) === undefined){
286 | throw "Function " + f_name + " does not exist."
287 | }
288 | else{
289 | TypedJS.log("wrapping...");
290 | TypedJS.log(arg_types);
291 | e_str = e_str + "=wrap("+e_str+")";
292 | TypedJS.log(e_str);
293 | return eval(e_str);
294 | }
295 | }
296 | else{
297 | window[f_name] = wrap(window[f_name]);
298 | return window[f_name];
299 | }
300 | }
301 | }
302 |
303 | if (typeof module !== 'undefined') {
304 | module.exports = TypedJS;
305 | }
306 |
307 |
--------------------------------------------------------------------------------
/typedjs_parser.js:
--------------------------------------------------------------------------------
1 | /* Jison generated parser */
2 | var typedjs_parser = (function(){
3 |
4 | var parser = {trace: function trace() { },
5 | yy: {},
6 | symbols_: {"error":2,"expressions":3,"BEGIN":4,"VAR":5,"::":6,"arg_list":7,"EOF":8,"e":9,"->":10,"primitive":11,"string":12,"char":13,"number":14,"boolean":15,"tuple":16,"(":17,")":18,"object":19,"{":20,"}":21,"list":22,"[":23,"]":24,"or":25,"|":26,",":27,":":28,"$accept":0,"$end":1},
7 | terminals_: {2:"error",4:"BEGIN",5:"VAR",6:"::",8:"EOF",10:"->",12:"string",13:"char",14:"number",15:"boolean",17:"(",18:")",20:"{",21:"}",23:"[",24:"]",26:"|",27:",",28:":"},
8 | productions_: [0,[3,5],[7,1],[7,3],[11,1],[11,1],[11,1],[11,1],[16,3],[19,3],[22,3],[22,3],[22,3],[22,3],[22,3],[25,3],[9,3],[9,1],[9,1],[9,1],[9,1],[9,1],[9,3],[9,1]],
9 | performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
10 |
11 | var $0 = $$.length - 1;
12 | switch (yystate) {
13 | case 1:return '{"func":"' + $$[$0-3] + '","args":[' +$$[$0-1] + ']}';
14 | break;
15 | case 2:this.$ = $$[$0];
16 | break;
17 | case 3:this.$ = $$[$0-2] +"," + $$[$0];
18 | break;
19 | case 4:this.$ = '"string"';
20 | break;
21 | case 5:this.$ = '"char"';
22 | break;
23 | case 6:this.$ = '"number"';
24 | break;
25 | case 7:this.$ = '"boolean"';
26 | break;
27 | case 8:this.$ = "["+$$[$0-1]+"]";
28 | break;
29 | case 9:this.$ = "{"+$$[$0-1]+"}";
30 | break;
31 | case 10:this.$ = '{"array":' + $$[$0-1] + '}';
32 | break;
33 | case 11:this.$ = '{"array":' + $$[$0-1] + '}';
34 | break;
35 | case 12:this.$ = '{"array":' + $$[$0-1] + '}';
36 | break;
37 | case 13:this.$ = '{"array":' + $$[$0-1] + '}';
38 | break;
39 | case 14:this.$ = '{"array":{"or":[' + $$[$0-1] + ']}}';
40 | break;
41 | case 15:this.$ = $$[$0-2] + ',' + $$[$0];
42 | break;
43 | case 16:this.$ = $$[$0-2]+','+$$[$0];
44 | break;
45 | case 17:this.$ = '{"or":[' + $$[$0] + ']}';
46 | break;
47 | case 22:this.$ = $$[$0-2] +':'+ $$[$0];
48 | break;
49 | case 23:this.$ = '"' + String(yytext) + '"';
50 | break;
51 | }
52 | },
53 | table: [{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:[1,4]},{5:[1,12],7:5,9:6,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{8:[1,20],10:[1,21]},{8:[2,2],10:[2,2],26:[1,24],27:[1,22],28:[1,23]},{8:[2,17],10:[2,17],18:[2,17],21:[2,17],24:[2,17],26:[2,17],27:[2,17],28:[2,17]},{8:[2,18],10:[2,18],18:[2,18],21:[2,18],24:[2,18],26:[2,18],27:[2,18],28:[2,18]},{8:[2,19],10:[2,19],18:[2,19],21:[2,19],24:[2,19],26:[2,19],27:[2,19],28:[2,19]},{8:[2,20],10:[2,20],18:[2,20],21:[2,20],24:[2,20],26:[2,20],27:[2,20],28:[2,20]},{8:[2,21],10:[2,21],18:[2,21],21:[2,21],24:[2,21],26:[2,21],27:[2,21],28:[2,21]},{8:[2,23],10:[2,23],18:[2,23],21:[2,23],24:[2,23],26:[2,23],27:[2,23],28:[2,23]},{5:[1,12],9:25,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:26,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:32,11:27,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:29,17:[1,14],19:28,20:[1,13],22:30,23:[1,15],25:31},{8:[2,4],10:[2,4],18:[2,4],21:[2,4],24:[2,4],26:[2,4],27:[2,4],28:[2,4]},{8:[2,5],10:[2,5],18:[2,5],21:[2,5],24:[2,5],26:[2,5],27:[2,5],28:[2,5]},{8:[2,6],10:[2,6],18:[2,6],21:[2,6],24:[2,6],26:[2,6],27:[2,6],28:[2,6]},{8:[2,7],10:[2,7],18:[2,7],21:[2,7],24:[2,7],26:[2,7],27:[2,7],28:[2,7]},{1:[2,1]},{5:[1,12],9:33,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:34,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:35,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:36,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{21:[1,37],26:[1,24],27:[1,22],28:[1,23]},{18:[1,38],26:[1,24],27:[1,22],28:[1,23]},{24:[1,39],26:[2,21],27:[2,21],28:[2,21]},{24:[1,40],26:[2,18],27:[2,18],28:[2,18]},{24:[1,41],26:[2,19],27:[2,19],28:[2,19]},{24:[1,42],26:[2,20],27:[2,20],28:[2,20]},{24:[1,43],26:[2,17],27:[2,17],28:[2,17]},{26:[1,24],27:[1,22],28:[1,23]},{8:[2,3],10:[2,3],26:[1,24],27:[1,22],28:[1,23]},{8:[2,16],10:[2,16],18:[2,16],21:[2,16],24:[2,16],26:[1,24],27:[2,16],28:[1,23]},{8:[2,22],10:[2,22],18:[2,22],21:[2,22],24:[2,22],26:[1,24],27:[2,22],28:[2,22]},{8:[2,15],10:[2,15],18:[2,15],21:[2,15],24:[2,15],26:[2,15],27:[2,15],28:[2,15]},{8:[2,9],10:[2,9],18:[2,9],21:[2,9],24:[2,9],26:[2,9],27:[2,9],28:[2,9]},{8:[2,8],10:[2,8],18:[2,8],21:[2,8],24:[2,8],26:[2,8],27:[2,8],28:[2,8]},{8:[2,10],10:[2,10],18:[2,10],21:[2,10],24:[2,10],26:[2,10],27:[2,10],28:[2,10]},{8:[2,11],10:[2,11],18:[2,11],21:[2,11],24:[2,11],26:[2,11],27:[2,11],28:[2,11]},{8:[2,12],10:[2,12],18:[2,12],21:[2,12],24:[2,12],26:[2,12],27:[2,12],28:[2,12]},{8:[2,13],10:[2,13],18:[2,13],21:[2,13],24:[2,13],26:[2,13],27:[2,13],28:[2,13]},{8:[2,14],10:[2,14],18:[2,14],21:[2,14],24:[2,14],26:[2,14],27:[2,14],28:[2,14]}],
54 | defaultActions: {20:[2,1]},
55 | parseError: function parseError(str, hash) {
56 | throw new Error(str);
57 | },
58 | parse: function parse(input) {
59 | var self = this,
60 | stack = [0],
61 | vstack = [null], // semantic value stack
62 | lstack = [], // location stack
63 | table = this.table,
64 | yytext = '',
65 | yylineno = 0,
66 | yyleng = 0,
67 | recovering = 0,
68 | TERROR = 2,
69 | EOF = 1;
70 |
71 | //this.reductionCount = this.shiftCount = 0;
72 |
73 | this.lexer.setInput(input);
74 | this.lexer.yy = this.yy;
75 | this.yy.lexer = this.lexer;
76 | if (typeof this.lexer.yylloc == 'undefined')
77 | this.lexer.yylloc = {};
78 | var yyloc = this.lexer.yylloc;
79 | lstack.push(yyloc);
80 |
81 | if (typeof this.yy.parseError === 'function')
82 | this.parseError = this.yy.parseError;
83 |
84 | function popStack (n) {
85 | stack.length = stack.length - 2*n;
86 | vstack.length = vstack.length - n;
87 | lstack.length = lstack.length - n;
88 | }
89 |
90 | function lex() {
91 | var token;
92 | token = self.lexer.lex() || 1; // $end = 1
93 | // if token isn't its numeric value, convert
94 | if (typeof token !== 'number') {
95 | token = self.symbols_[token] || token;
96 | }
97 | return token;
98 | };
99 |
100 | var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
101 | while (true) {
102 | // retreive state number from top of stack
103 | state = stack[stack.length-1];
104 |
105 | // use default actions if available
106 | if (this.defaultActions[state]) {
107 | action = this.defaultActions[state];
108 | } else {
109 | if (symbol == null)
110 | symbol = lex();
111 | // read action for current state and first input
112 | action = table[state] && table[state][symbol];
113 | }
114 |
115 | // handle parse error
116 | if (typeof action === 'undefined' || !action.length || !action[0]) {
117 |
118 | if (!recovering) {
119 | // Report error
120 | expected = [];
121 | for (p in table[state]) if (this.terminals_[p] && p > 2) {
122 | expected.push("'"+this.terminals_[p]+"'");
123 | }
124 | var errStr = '';
125 | if (this.lexer.showPosition) {
126 | errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ');
127 | } else {
128 | errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
129 | (symbol == 1 /*EOF*/ ? "end of input" :
130 | ("'"+(this.terminals_[symbol] || symbol)+"'"));
131 | }
132 | this.parseError(errStr,
133 | {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
134 | }
135 |
136 | // just recovered from another error
137 | if (recovering == 3) {
138 | if (symbol == EOF) {
139 | throw new Error(errStr || 'Parsing halted.');
140 | }
141 |
142 | // discard current lookahead and grab another
143 | yyleng = this.lexer.yyleng;
144 | yytext = this.lexer.yytext;
145 | yylineno = this.lexer.yylineno;
146 | yyloc = this.lexer.yylloc;
147 | symbol = lex();
148 | }
149 |
150 | // try to recover from error
151 | while (1) {
152 | // check for error recovery rule in this state
153 | if ((TERROR.toString()) in table[state]) {
154 | break;
155 | }
156 | if (state == 0) {
157 | throw new Error(errStr || 'Parsing halted.');
158 | }
159 | popStack(1);
160 | state = stack[stack.length-1];
161 | }
162 |
163 | preErrorSymbol = symbol; // save the lookahead token
164 | symbol = TERROR; // insert generic error symbol as new lookahead
165 | state = stack[stack.length-1];
166 | action = table[state] && table[state][TERROR];
167 | recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
168 | }
169 |
170 | // this shouldn't happen, unless resolve defaults are off
171 | if (action[0] instanceof Array && action.length > 1) {
172 | throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
173 | }
174 |
175 | switch (action[0]) {
176 |
177 | case 1: // shift
178 | //this.shiftCount++;
179 |
180 | stack.push(symbol);
181 | vstack.push(this.lexer.yytext);
182 | lstack.push(this.lexer.yylloc);
183 | stack.push(action[1]); // push state
184 | symbol = null;
185 | if (!preErrorSymbol) { // normal execution/no error
186 | yyleng = this.lexer.yyleng;
187 | yytext = this.lexer.yytext;
188 | yylineno = this.lexer.yylineno;
189 | yyloc = this.lexer.yylloc;
190 | if (recovering > 0)
191 | recovering--;
192 | } else { // error just occurred, resume old lookahead f/ before error
193 | symbol = preErrorSymbol;
194 | preErrorSymbol = null;
195 | }
196 | break;
197 |
198 | case 2: // reduce
199 | //this.reductionCount++;
200 |
201 | len = this.productions_[action[1]][1];
202 |
203 | // perform semantic action
204 | yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
205 | // default location, uses first token for firsts, last for lasts
206 | yyval._$ = {
207 | first_line: lstack[lstack.length-(len||1)].first_line,
208 | last_line: lstack[lstack.length-1].last_line,
209 | first_column: lstack[lstack.length-(len||1)].first_column,
210 | last_column: lstack[lstack.length-1].last_column
211 | };
212 | r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
213 |
214 | if (typeof r !== 'undefined') {
215 | return r;
216 | }
217 |
218 | // pop off stack
219 | if (len) {
220 | stack = stack.slice(0,-1*len*2);
221 | vstack = vstack.slice(0, -1*len);
222 | lstack = lstack.slice(0, -1*len);
223 | }
224 |
225 | stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
226 | vstack.push(yyval.$);
227 | lstack.push(yyval._$);
228 | // goto new state = table[STATE][NONTERMINAL]
229 | newState = table[stack[stack.length-2]][stack[stack.length-1]];
230 | stack.push(newState);
231 | break;
232 |
233 | case 3: // accept
234 | return true;
235 | }
236 |
237 | }
238 |
239 | return true;
240 | }};/* Jison generated lexer */
241 | var lexer = (function(){
242 |
243 | var lexer = ({EOF:1,
244 | parseError:function parseError(str, hash) {
245 | if (this.yy.parseError) {
246 | this.yy.parseError(str, hash);
247 | } else {
248 | throw new Error(str);
249 | }
250 | },
251 | setInput:function (input) {
252 | this._input = input;
253 | this._more = this._less = this.done = false;
254 | this.yylineno = this.yyleng = 0;
255 | this.yytext = this.matched = this.match = '';
256 | this.conditionStack = ['INITIAL'];
257 | this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
258 | return this;
259 | },
260 | input:function () {
261 | var ch = this._input[0];
262 | this.yytext+=ch;
263 | this.yyleng++;
264 | this.match+=ch;
265 | this.matched+=ch;
266 | var lines = ch.match(/\n/);
267 | if (lines) this.yylineno++;
268 | this._input = this._input.slice(1);
269 | return ch;
270 | },
271 | unput:function (ch) {
272 | this._input = ch + this._input;
273 | return this;
274 | },
275 | more:function () {
276 | this._more = true;
277 | return this;
278 | },
279 | pastInput:function () {
280 | var past = this.matched.substr(0, this.matched.length - this.match.length);
281 | return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
282 | },
283 | upcomingInput:function () {
284 | var next = this.match;
285 | if (next.length < 20) {
286 | next += this._input.substr(0, 20-next.length);
287 | }
288 | return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
289 | },
290 | showPosition:function () {
291 | var pre = this.pastInput();
292 | var c = new Array(pre.length + 1).join("-");
293 | return pre + this.upcomingInput() + "\n" + c+"^";
294 | },
295 | next:function () {
296 | if (this.done) {
297 | return this.EOF;
298 | }
299 | if (!this._input) this.done = true;
300 |
301 | var token,
302 | match,
303 | col,
304 | lines;
305 | if (!this._more) {
306 | this.yytext = '';
307 | this.match = '';
308 | }
309 | var rules = this._currentRules();
310 | for (var i=0;i < rules.length; i++) {
311 | match = this._input.match(this.rules[rules[i]]);
312 | if (match) {
313 | lines = match[0].match(/\n.*/g);
314 | if (lines) this.yylineno += lines.length;
315 | this.yylloc = {first_line: this.yylloc.last_line,
316 | last_line: this.yylineno+1,
317 | first_column: this.yylloc.last_column,
318 | last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
319 | this.yytext += match[0];
320 | this.match += match[0];
321 | this.matches = match;
322 | this.yyleng = this.yytext.length;
323 | this._more = false;
324 | this._input = this._input.slice(match[0].length);
325 | this.matched += match[0];
326 | token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
327 | if (token) return token;
328 | else return;
329 | }
330 | }
331 | if (this._input === "") {
332 | return this.EOF;
333 | } else {
334 | this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
335 | {text: "", token: null, line: this.yylineno});
336 | }
337 | },
338 | lex:function lex() {
339 | var r = this.next();
340 | if (typeof r !== 'undefined') {
341 | return r;
342 | } else {
343 | return this.lex();
344 | }
345 | },
346 | begin:function begin(condition) {
347 | this.conditionStack.push(condition);
348 | },
349 | popState:function popState() {
350 | return this.conditionStack.pop();
351 | },
352 | _currentRules:function _currentRules() {
353 | return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
354 | }});
355 | lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
356 |
357 | var YYSTATE=YY_START
358 | switch($avoiding_name_collisions) {
359 | case 0:/* skip whitespace */
360 | break;
361 | case 1:return 12
362 | break;
363 | case 2:return 14
364 | break;
365 | case 3:return 13
366 | break;
367 | case 4:return 15
368 | break;
369 | case 5:return 5
370 | break;
371 | case 6:return 4
372 | break;
373 | case 7:return 27
374 | break;
375 | case 8:return 17
376 | break;
377 | case 9:return 18
378 | break;
379 | case 10:return 23
380 | break;
381 | case 11:return 24
382 | break;
383 | case 12:return 20
384 | break;
385 | case 13:return 21
386 | break;
387 | case 14:return 6
388 | break;
389 | case 15:return 10
390 | break;
391 | case 16:return 28
392 | break;
393 | case 17:return 26
394 | break;
395 | case 18:return 8
396 | break;
397 | case 19:return 'INVALID'
398 | break;
399 | }
400 | };
401 | lexer.rules = [/^\s+/,/^String\b/,/^Number\b/,/^Char\b/,/^Boolean\b/,/^([a-z]|[A-Z]|_|\.)+/,/^\/\/\+/,/^,/,/^\(/,/^\)/,/^\[/,/^\]/,/^\{/,/^\}/,/^::/,/^->/,/^:/,/^\|/,/^$/,/^./];
402 | lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],"inclusive":true}};return lexer;})()
403 | parser.lexer = lexer;
404 | return parser;
405 | })();
406 | if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
407 | exports.parser = typedjs_parser;
408 | exports.parse = function () { return typedjs_parser.parse.apply(typedjs_parser, arguments); }
409 | exports.main = function commonjsMain(args) {
410 | if (!args[1])
411 | throw new Error('Usage: '+args[0]+' FILE');
412 | if (typeof process !== 'undefined') {
413 | var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
414 | } else {
415 | var cwd = require("file").path(require("file").cwd());
416 | var source = cwd.join(args[1]).read({charset: "utf-8"});
417 | }
418 | return exports.parser.parse(source);
419 | }
420 | if (typeof module !== 'undefined' && require.main === module) {
421 | exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
422 | }
423 | }
--------------------------------------------------------------------------------
/_site/typedjs_parser.js:
--------------------------------------------------------------------------------
1 | /* Jison generated parser */
2 | var typedjs_parser = (function(){
3 |
4 | var parser = {trace: function trace() { },
5 | yy: {},
6 | symbols_: {"error":2,"expressions":3,"BEGIN":4,"VAR":5,"::":6,"arg_list":7,"EOF":8,"e":9,"->":10,"primitive":11,"string":12,"char":13,"number":14,"boolean":15,"tuple":16,"(":17,")":18,"object":19,"{":20,"}":21,"list":22,"[":23,"]":24,"or":25,"|":26,",":27,":":28,"$accept":0,"$end":1},
7 | terminals_: {2:"error",4:"BEGIN",5:"VAR",6:"::",8:"EOF",10:"->",12:"string",13:"char",14:"number",15:"boolean",17:"(",18:")",20:"{",21:"}",23:"[",24:"]",26:"|",27:",",28:":"},
8 | productions_: [0,[3,5],[7,1],[7,3],[11,1],[11,1],[11,1],[11,1],[16,3],[19,3],[22,3],[22,3],[22,3],[22,3],[22,3],[25,3],[9,3],[9,1],[9,1],[9,1],[9,1],[9,1],[9,3],[9,1]],
9 | performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
10 |
11 | var $0 = $$.length - 1;
12 | switch (yystate) {
13 | case 1:return '{"func":"' + $$[$0-3] + '","args":[' +$$[$0-1] + ']}';
14 | break;
15 | case 2:this.$ = $$[$0];
16 | break;
17 | case 3:this.$ = $$[$0-2] +"," + $$[$0];
18 | break;
19 | case 4:this.$ = '"string"';
20 | break;
21 | case 5:this.$ = '"char"';
22 | break;
23 | case 6:this.$ = '"number"';
24 | break;
25 | case 7:this.$ = '"boolean"';
26 | break;
27 | case 8:this.$ = "["+$$[$0-1]+"]";
28 | break;
29 | case 9:this.$ = "{"+$$[$0-1]+"}";
30 | break;
31 | case 10:this.$ = '{"array":' + $$[$0-1] + '}';
32 | break;
33 | case 11:this.$ = '{"array":' + $$[$0-1] + '}';
34 | break;
35 | case 12:this.$ = '{"array":' + $$[$0-1] + '}';
36 | break;
37 | case 13:this.$ = '{"array":' + $$[$0-1] + '}';
38 | break;
39 | case 14:this.$ = '{"array":{"or":[' + $$[$0-1] + ']}}';
40 | break;
41 | case 15:this.$ = $$[$0-2] + ',' + $$[$0];
42 | break;
43 | case 16:this.$ = $$[$0-2]+','+$$[$0];
44 | break;
45 | case 17:this.$ = '{"or":[' + $$[$0] + ']}';
46 | break;
47 | case 22:this.$ = $$[$0-2] +':'+ $$[$0];
48 | break;
49 | case 23:this.$ = '"' + String(yytext) + '"';
50 | break;
51 | }
52 | },
53 | table: [{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:[1,4]},{5:[1,12],7:5,9:6,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{8:[1,20],10:[1,21]},{8:[2,2],10:[2,2],26:[1,24],27:[1,22],28:[1,23]},{8:[2,17],10:[2,17],18:[2,17],21:[2,17],24:[2,17],26:[2,17],27:[2,17],28:[2,17]},{8:[2,18],10:[2,18],18:[2,18],21:[2,18],24:[2,18],26:[2,18],27:[2,18],28:[2,18]},{8:[2,19],10:[2,19],18:[2,19],21:[2,19],24:[2,19],26:[2,19],27:[2,19],28:[2,19]},{8:[2,20],10:[2,20],18:[2,20],21:[2,20],24:[2,20],26:[2,20],27:[2,20],28:[2,20]},{8:[2,21],10:[2,21],18:[2,21],21:[2,21],24:[2,21],26:[2,21],27:[2,21],28:[2,21]},{8:[2,23],10:[2,23],18:[2,23],21:[2,23],24:[2,23],26:[2,23],27:[2,23],28:[2,23]},{5:[1,12],9:25,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:26,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:32,11:27,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:29,17:[1,14],19:28,20:[1,13],22:30,23:[1,15],25:31},{8:[2,4],10:[2,4],18:[2,4],21:[2,4],24:[2,4],26:[2,4],27:[2,4],28:[2,4]},{8:[2,5],10:[2,5],18:[2,5],21:[2,5],24:[2,5],26:[2,5],27:[2,5],28:[2,5]},{8:[2,6],10:[2,6],18:[2,6],21:[2,6],24:[2,6],26:[2,6],27:[2,6],28:[2,6]},{8:[2,7],10:[2,7],18:[2,7],21:[2,7],24:[2,7],26:[2,7],27:[2,7],28:[2,7]},{1:[2,1]},{5:[1,12],9:33,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:34,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:35,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{5:[1,12],9:36,11:11,12:[1,16],13:[1,17],14:[1,18],15:[1,19],16:9,17:[1,14],19:8,20:[1,13],22:10,23:[1,15],25:7},{21:[1,37],26:[1,24],27:[1,22],28:[1,23]},{18:[1,38],26:[1,24],27:[1,22],28:[1,23]},{24:[1,39],26:[2,21],27:[2,21],28:[2,21]},{24:[1,40],26:[2,18],27:[2,18],28:[2,18]},{24:[1,41],26:[2,19],27:[2,19],28:[2,19]},{24:[1,42],26:[2,20],27:[2,20],28:[2,20]},{24:[1,43],26:[2,17],27:[2,17],28:[2,17]},{26:[1,24],27:[1,22],28:[1,23]},{8:[2,3],10:[2,3],26:[1,24],27:[1,22],28:[1,23]},{8:[2,16],10:[2,16],18:[2,16],21:[2,16],24:[2,16],26:[1,24],27:[2,16],28:[1,23]},{8:[2,22],10:[2,22],18:[2,22],21:[2,22],24:[2,22],26:[1,24],27:[2,22],28:[2,22]},{8:[2,15],10:[2,15],18:[2,15],21:[2,15],24:[2,15],26:[2,15],27:[2,15],28:[2,15]},{8:[2,9],10:[2,9],18:[2,9],21:[2,9],24:[2,9],26:[2,9],27:[2,9],28:[2,9]},{8:[2,8],10:[2,8],18:[2,8],21:[2,8],24:[2,8],26:[2,8],27:[2,8],28:[2,8]},{8:[2,10],10:[2,10],18:[2,10],21:[2,10],24:[2,10],26:[2,10],27:[2,10],28:[2,10]},{8:[2,11],10:[2,11],18:[2,11],21:[2,11],24:[2,11],26:[2,11],27:[2,11],28:[2,11]},{8:[2,12],10:[2,12],18:[2,12],21:[2,12],24:[2,12],26:[2,12],27:[2,12],28:[2,12]},{8:[2,13],10:[2,13],18:[2,13],21:[2,13],24:[2,13],26:[2,13],27:[2,13],28:[2,13]},{8:[2,14],10:[2,14],18:[2,14],21:[2,14],24:[2,14],26:[2,14],27:[2,14],28:[2,14]}],
54 | defaultActions: {20:[2,1]},
55 | parseError: function parseError(str, hash) {
56 | throw new Error(str);
57 | },
58 | parse: function parse(input) {
59 | var self = this,
60 | stack = [0],
61 | vstack = [null], // semantic value stack
62 | lstack = [], // location stack
63 | table = this.table,
64 | yytext = '',
65 | yylineno = 0,
66 | yyleng = 0,
67 | recovering = 0,
68 | TERROR = 2,
69 | EOF = 1;
70 |
71 | //this.reductionCount = this.shiftCount = 0;
72 |
73 | this.lexer.setInput(input);
74 | this.lexer.yy = this.yy;
75 | this.yy.lexer = this.lexer;
76 | if (typeof this.lexer.yylloc == 'undefined')
77 | this.lexer.yylloc = {};
78 | var yyloc = this.lexer.yylloc;
79 | lstack.push(yyloc);
80 |
81 | if (typeof this.yy.parseError === 'function')
82 | this.parseError = this.yy.parseError;
83 |
84 | function popStack (n) {
85 | stack.length = stack.length - 2*n;
86 | vstack.length = vstack.length - n;
87 | lstack.length = lstack.length - n;
88 | }
89 |
90 | function lex() {
91 | var token;
92 | token = self.lexer.lex() || 1; // $end = 1
93 | // if token isn't its numeric value, convert
94 | if (typeof token !== 'number') {
95 | token = self.symbols_[token] || token;
96 | }
97 | return token;
98 | };
99 |
100 | var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
101 | while (true) {
102 | // retreive state number from top of stack
103 | state = stack[stack.length-1];
104 |
105 | // use default actions if available
106 | if (this.defaultActions[state]) {
107 | action = this.defaultActions[state];
108 | } else {
109 | if (symbol == null)
110 | symbol = lex();
111 | // read action for current state and first input
112 | action = table[state] && table[state][symbol];
113 | }
114 |
115 | // handle parse error
116 | if (typeof action === 'undefined' || !action.length || !action[0]) {
117 |
118 | if (!recovering) {
119 | // Report error
120 | expected = [];
121 | for (p in table[state]) if (this.terminals_[p] && p > 2) {
122 | expected.push("'"+this.terminals_[p]+"'");
123 | }
124 | var errStr = '';
125 | if (this.lexer.showPosition) {
126 | errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ');
127 | } else {
128 | errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
129 | (symbol == 1 /*EOF*/ ? "end of input" :
130 | ("'"+(this.terminals_[symbol] || symbol)+"'"));
131 | }
132 | this.parseError(errStr,
133 | {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
134 | }
135 |
136 | // just recovered from another error
137 | if (recovering == 3) {
138 | if (symbol == EOF) {
139 | throw new Error(errStr || 'Parsing halted.');
140 | }
141 |
142 | // discard current lookahead and grab another
143 | yyleng = this.lexer.yyleng;
144 | yytext = this.lexer.yytext;
145 | yylineno = this.lexer.yylineno;
146 | yyloc = this.lexer.yylloc;
147 | symbol = lex();
148 | }
149 |
150 | // try to recover from error
151 | while (1) {
152 | // check for error recovery rule in this state
153 | if ((TERROR.toString()) in table[state]) {
154 | break;
155 | }
156 | if (state == 0) {
157 | throw new Error(errStr || 'Parsing halted.');
158 | }
159 | popStack(1);
160 | state = stack[stack.length-1];
161 | }
162 |
163 | preErrorSymbol = symbol; // save the lookahead token
164 | symbol = TERROR; // insert generic error symbol as new lookahead
165 | state = stack[stack.length-1];
166 | action = table[state] && table[state][TERROR];
167 | recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
168 | }
169 |
170 | // this shouldn't happen, unless resolve defaults are off
171 | if (action[0] instanceof Array && action.length > 1) {
172 | throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
173 | }
174 |
175 | switch (action[0]) {
176 |
177 | case 1: // shift
178 | //this.shiftCount++;
179 |
180 | stack.push(symbol);
181 | vstack.push(this.lexer.yytext);
182 | lstack.push(this.lexer.yylloc);
183 | stack.push(action[1]); // push state
184 | symbol = null;
185 | if (!preErrorSymbol) { // normal execution/no error
186 | yyleng = this.lexer.yyleng;
187 | yytext = this.lexer.yytext;
188 | yylineno = this.lexer.yylineno;
189 | yyloc = this.lexer.yylloc;
190 | if (recovering > 0)
191 | recovering--;
192 | } else { // error just occurred, resume old lookahead f/ before error
193 | symbol = preErrorSymbol;
194 | preErrorSymbol = null;
195 | }
196 | break;
197 |
198 | case 2: // reduce
199 | //this.reductionCount++;
200 |
201 | len = this.productions_[action[1]][1];
202 |
203 | // perform semantic action
204 | yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
205 | // default location, uses first token for firsts, last for lasts
206 | yyval._$ = {
207 | first_line: lstack[lstack.length-(len||1)].first_line,
208 | last_line: lstack[lstack.length-1].last_line,
209 | first_column: lstack[lstack.length-(len||1)].first_column,
210 | last_column: lstack[lstack.length-1].last_column
211 | };
212 | r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
213 |
214 | if (typeof r !== 'undefined') {
215 | return r;
216 | }
217 |
218 | // pop off stack
219 | if (len) {
220 | stack = stack.slice(0,-1*len*2);
221 | vstack = vstack.slice(0, -1*len);
222 | lstack = lstack.slice(0, -1*len);
223 | }
224 |
225 | stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
226 | vstack.push(yyval.$);
227 | lstack.push(yyval._$);
228 | // goto new state = table[STATE][NONTERMINAL]
229 | newState = table[stack[stack.length-2]][stack[stack.length-1]];
230 | stack.push(newState);
231 | break;
232 |
233 | case 3: // accept
234 | return true;
235 | }
236 |
237 | }
238 |
239 | return true;
240 | }};/* Jison generated lexer */
241 | var lexer = (function(){
242 |
243 | var lexer = ({EOF:1,
244 | parseError:function parseError(str, hash) {
245 | if (this.yy.parseError) {
246 | this.yy.parseError(str, hash);
247 | } else {
248 | throw new Error(str);
249 | }
250 | },
251 | setInput:function (input) {
252 | this._input = input;
253 | this._more = this._less = this.done = false;
254 | this.yylineno = this.yyleng = 0;
255 | this.yytext = this.matched = this.match = '';
256 | this.conditionStack = ['INITIAL'];
257 | this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
258 | return this;
259 | },
260 | input:function () {
261 | var ch = this._input[0];
262 | this.yytext+=ch;
263 | this.yyleng++;
264 | this.match+=ch;
265 | this.matched+=ch;
266 | var lines = ch.match(/\n/);
267 | if (lines) this.yylineno++;
268 | this._input = this._input.slice(1);
269 | return ch;
270 | },
271 | unput:function (ch) {
272 | this._input = ch + this._input;
273 | return this;
274 | },
275 | more:function () {
276 | this._more = true;
277 | return this;
278 | },
279 | pastInput:function () {
280 | var past = this.matched.substr(0, this.matched.length - this.match.length);
281 | return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
282 | },
283 | upcomingInput:function () {
284 | var next = this.match;
285 | if (next.length < 20) {
286 | next += this._input.substr(0, 20-next.length);
287 | }
288 | return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
289 | },
290 | showPosition:function () {
291 | var pre = this.pastInput();
292 | var c = new Array(pre.length + 1).join("-");
293 | return pre + this.upcomingInput() + "\n" + c+"^";
294 | },
295 | next:function () {
296 | if (this.done) {
297 | return this.EOF;
298 | }
299 | if (!this._input) this.done = true;
300 |
301 | var token,
302 | match,
303 | col,
304 | lines;
305 | if (!this._more) {
306 | this.yytext = '';
307 | this.match = '';
308 | }
309 | var rules = this._currentRules();
310 | for (var i=0;i < rules.length; i++) {
311 | match = this._input.match(this.rules[rules[i]]);
312 | if (match) {
313 | lines = match[0].match(/\n.*/g);
314 | if (lines) this.yylineno += lines.length;
315 | this.yylloc = {first_line: this.yylloc.last_line,
316 | last_line: this.yylineno+1,
317 | first_column: this.yylloc.last_column,
318 | last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
319 | this.yytext += match[0];
320 | this.match += match[0];
321 | this.matches = match;
322 | this.yyleng = this.yytext.length;
323 | this._more = false;
324 | this._input = this._input.slice(match[0].length);
325 | this.matched += match[0];
326 | token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
327 | if (token) return token;
328 | else return;
329 | }
330 | }
331 | if (this._input === "") {
332 | return this.EOF;
333 | } else {
334 | this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
335 | {text: "", token: null, line: this.yylineno});
336 | }
337 | },
338 | lex:function lex() {
339 | var r = this.next();
340 | if (typeof r !== 'undefined') {
341 | return r;
342 | } else {
343 | return this.lex();
344 | }
345 | },
346 | begin:function begin(condition) {
347 | this.conditionStack.push(condition);
348 | },
349 | popState:function popState() {
350 | return this.conditionStack.pop();
351 | },
352 | _currentRules:function _currentRules() {
353 | return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
354 | }});
355 | lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
356 |
357 | var YYSTATE=YY_START
358 | switch($avoiding_name_collisions) {
359 | case 0:/* skip whitespace */
360 | break;
361 | case 1:return 12
362 | break;
363 | case 2:return 14
364 | break;
365 | case 3:return 13
366 | break;
367 | case 4:return 15
368 | break;
369 | case 5:return 5
370 | break;
371 | case 6:return 4
372 | break;
373 | case 7:return 27
374 | break;
375 | case 8:return 17
376 | break;
377 | case 9:return 18
378 | break;
379 | case 10:return 23
380 | break;
381 | case 11:return 24
382 | break;
383 | case 12:return 20
384 | break;
385 | case 13:return 21
386 | break;
387 | case 14:return 6
388 | break;
389 | case 15:return 10
390 | break;
391 | case 16:return 28
392 | break;
393 | case 17:return 26
394 | break;
395 | case 18:return 8
396 | break;
397 | case 19:return 'INVALID'
398 | break;
399 | }
400 | };
401 | lexer.rules = [/^\s+/,/^String\b/,/^Number\b/,/^Char\b/,/^Boolean\b/,/^([a-z]|[A-Z]|_|\.)+/,/^\/\/\+/,/^,/,/^\(/,/^\)/,/^\[/,/^\]/,/^\{/,/^\}/,/^::/,/^->/,/^:/,/^\|/,/^$/,/^./];
402 | lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],"inclusive":true}};return lexer;})()
403 | parser.lexer = lexer;
404 | return parser;
405 | })();
406 | if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
407 | exports.parser = typedjs_parser;
408 | exports.parse = function () { return typedjs_parser.parse.apply(typedjs_parser, arguments); }
409 | exports.main = function commonjsMain(args) {
410 | if (!args[1])
411 | throw new Error('Usage: '+args[0]+' FILE');
412 | if (typeof process !== 'undefined') {
413 | var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
414 | } else {
415 | var cwd = require("file").path(require("file").cwd());
416 | var source = cwd.join(args[1]).read({charset: "utf-8"});
417 | }
418 | return exports.parser.parse(source);
419 | }
420 | if (typeof module !== 'undefined' && require.main === module) {
421 | exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
422 | }
423 | }
--------------------------------------------------------------------------------
/_site/examples/jquery-1.7.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery v1.7 jquery.com | jquery.org/license */
2 | (function(a,b){function cA(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cx(a){if(!cm[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cn||(cn=c.createElement("iframe"),cn.frameBorder=cn.width=cn.height=0),b.appendChild(cn);if(!co||!cn.createElement)co=(cn.contentWindow||cn.contentDocument).document,co.write((c.compatMode==="CSS1Compat"?"":"")+""),co.close();d=co.createElement(a),co.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cn)}cm[a]=e}return cm[a]}function cw(a,b){var c={};f.each(cs.concat.apply([],cs.slice(0,b)),function(){c[this]=a});return c}function cv(){ct=b}function cu(){setTimeout(cv,0);return ct=f.now()}function cl(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ck(){try{return new a.XMLHttpRequest}catch(b){}}function ce(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bB(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function br(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bi,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bq(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bp(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bp)}function bp(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bo(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bn(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bm(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(){return!0}function M(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.add(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return a!=null&&m.test(a)&&!isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,unknownElems:!!a.getElementsByTagName("nav").length,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",enctype:!!c.createElement("form").enctype,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.lastChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-999px",top:"-999px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;f(function(){var a,b,d,e,g,h,i=1,j="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",l="visibility:hidden;border:0;",n="style='"+j+"border:5px solid #000;padding:0;'",p="