aboutsummaryrefslogtreecommitdiff
path: root/test.js
blob: c8ee5f023859eedf87078c2a7c78f7672194da91 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
var acorn = require('acorn/dist/acorn_loose');
var walk = require("acorn/dist/walk");
var acorn_base = require("acorn");




/**
*	Loop over a function and get a list of things being called.
*
*	Tests to see if the function calls itself.
*	
*	Note: If it is an anonmyous function, recursion isn't possible.
*
*/
function get_function_names(input_node_src,scope){
	var func_name = "";
	var flag = true;

	// The name of the function can't appear anywhere.
	// No bracket suffix notation either.
	console.log("Searching for identifier '"+scope+"' in this code:");
	console.log(input_node_src);
	
	var tokens = acorn_base.tokenizer(input_node_src);
	var toke = tokens.getToken();
	while(toke.type != acorn_base.tokTypes.eof){
		if(toke.type.label == "name" && scope == toke.value){
			return true;
		}
		toke = tokens.getToken();
	}

	return false;
}




window.onload = function () {

	document.getElementById("parse").addEventListener("click",function(){
		var res = true;		

		var script = document.getElementById("input").value;

		var ast = acorn.parse_dammit(script).body[0];
		document.getElementById("output").innerHTML = JSON.stringify(ast, null, "\t"); // Indented with tab

		var flag = false;
		var amtloops = 0;

		// COUNTS LOOPS AND CONDITIONALS
		walk.simple(ast, {
			ForInStatement(node){
				if(amtloops > 3){return;}				
				console.log("ForInStatement");
				amtloops++;
			},
			ForStatement(node){
				if(amtloops > 3){return;}
				console.log("ForStatement");
				amtloops++;
			},
			DoWhileStatement(node){
				if(amtloops > 3){return;}
				console.log("DoWhileStatement");
				amtloops++;
			},
			WhileStatement(node){
				if(amtloops > 3){return;}
				console.log("WhileStatement");
				amtloops++;
			},
			IfStatement(node){
				if(amtloops > 3){return;}
				console.log("IfStatement");
				amtloops++;
			},
			SwitchStatement(node){
				if(amtloops > 3){return;}
				console.log("SwitchStatement");
				amtloops++;
			}
		});

		if(amtloops > 3){
			console.log("%c NONTRIVIAL: Too many loops/conditionals.","color:red");
			// TODO: return here
		}
		// DETECT RECURSION
		var nontrivial = false;
		walk.simple(ast, {
			CallExpression(node){
				if(nontrivial == true){
					return;
				}
				test_function_name(node.callee.name);
			}
		});

		if(nontrivial == true){
			console.log("%c NONTRIVIAL: Recursion detected.","color:red");
			res = false;// TODO: return here
		}




		document.getElementById("output").innerHTML =  res + "\n\n" + document.getElementById("output").innerHTML;		

	});

}