Is there a way to inspect which variables (and lines of code) contribute to a value in Javascript? For example if I would inspect the parameter input in this code
let x=5;
let y=x+3;
function a(input) {
// analyzing input in this scope/context,
// i would like to see that it is a combination of
// x from line 1 and a constant '3' from line 2.
inspectDataFlow(input);
}
a(y);
I would like to get as output a data structure that would be something like this:
input (line 8)
y (line 2)
x (line 1)
"3" (line 2)
Purpose and goal
My goal for this would be to have a tool where you could see/change the value of a Javascript variable and it would automatically adjust the variables that the value originates from.
For example, you could have a function to draw shapes. And when you adjust visually the shapes that were drawn, the original variables for color, shape positions etc would update accordingly.
Something a bit like this but for editing arbitrary code, even after a user has modified the code lines:
http://yining1023.github.io/p5PlayGround/
Another idea I was thinking was to visualize how a variable has been composed: which lines it is a combination of and how they affect the result.
Potential approach
One approach for this I'm thinking about is to add instrumentation to the code with Esprima/Acorn that is then called on runtime. The instrumentation would keep track on which variables have been called on which lines (and scopes) and how they relate to each other, a bit like this:
http://alltom.com/pages/instrumenting-javascript/
I wonder if this would work and if there is a framework one could use for this? Or if one would have to do the instrumentation from scratch?
Related themes
This could be related to data flow analysis or use-define chains, but I'm not sure, since I don't know much about compilers.
https://en.wikipedia.org/wiki/Use-define_chain
My first idea was that this could be done using static analysis with something like Esprima/Acorn, but I'm not sure if that is the right way, or if this could be done with some custom Javascript interpreter instead.
http://tobyho.com/2013/12/02/fun-with-esprima/
Related
I am using the p5.js library to create Tetris. When someone gets a line clear (that is, a full line has been filled with Tetris blocks) then the tiles that made that line fill up should be removed/turned off.
What would be the best way to do this? For all visibility aspects of a tile, I use a show() function that draws a rectangle to show the tile. Should I add a variable to the object and check if that is true because executing the show function? Or is there a built-in method or function that makes removing an object easy? I can't seem to find anything like this online
It is hard to answer if we do not know how your tiles are represented in your program.
The method I recommend is to remove the tile from it's container structure altogether.
For example, if the state of your game is stored in a matrix, simply empty the cells that constitute a line. This way, your show() function should not be called at all.
Removing the tile from the container will work, but if its difficult then there is another way.
Have a variable to track whether the tile is being used and have its default be true e.g this.inPlay = true
Only update and show a tile if its inplay is true:
if (tile.inPlay == true) {
tile.update()
tile.show()
}
'''
If you want to remove it, just set its inplay to false
PS. a great tutorial for p5.js is on youtube (made by the coding train)
PPS. just search 'coding train p5.js tutorial' on youtube
This obviuosly works perfectly:<script>alert(5*8-4)</script>
but i need to solve whatever someone puts inside an input box.
Heres what I thought of doing: I would get the value of the input, into a variable. then I would use
document.write("<script>alert("+theinputvalue+")<script>");
or do this:
var string="<script>alert("+theinputvalue+")<script>";document.write(string);
but nothing works.
Is it even possible to do this? if not, tell my what simple other system I could use.
eventually, I will use it to graph lines like this:
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d")
for(var x=-100; x<100; x=x+.2){
y = .1*(x*x)
ctx.fillRect(x+50, -1*y+50, 2, 2);
}
http://jsfiddle.net/KGgq4/
eval('5*8-4')
will result in 36
I'm not aware of any library that is doing that (this doesn't mean that there are no such it simply means I never actually needed that) but what you should end up doing is to build an automata that will parse input string and transform it to a proper graph with proper transformations. This is not very easy topic and if you want to go this route you should start reading on arithmetic expressions parsing algorithms (sorry I do not have any solution in place).
Or you can cheat and define types of equations that will be selected by user. Once user selects type of equation you should be able show user inputs where user will be able to select coefficients. You can read those coefficients into different variables and apply transformations in your draw procedure (For example if user will select type sin(x) you know that general equation has following formula: y = k*sin(a*x + b) + c. So once it is selected you can allow user to enter k, a, b, c and based on that input calculate appropriate locations of points for your graph.)
Well, third solution could involve "eval ", but usually you should avoid eval at any cost (B/c it is straight forward JavaScript injection which may be an OK for this case but may get you in trouble later in your life. ).
You can use math.js, which comes with an advanced expression parser. It supports definition of variables and functions.
// create an instance of math.js
var math = mathjs();
// evaluate an expression
math.eval('5*8-4'); // 36
// user defined function (returns a native JavaScript function)
var f = math.eval('f(x) = 2*x^2 + 6');
// use the function (for graphing or something)
f(2); // 14
Based on this work: http://bl.ocks.org/mbostock/7882658
If I substitute the automatic nodes creation by a JSON.stringify() output of the automatically generated data like this...
var nodes = [
{"cluster":2,"radius":1.6180680659922448},
{"cluster":0,"radius":3.3575295077569},
{"cluster":1,"radius":0.9569281165554346},
{"cluster":3,"radius":10.7245554165012}
];
...I get an exception "cannot read property x of undefined" on the line:
var x = d.x - cluster.x,
This is inside the cluster(alpha) function. So, apparently the d3.map function that automatically generates the data is putting something in the structure that the JSON stringification has not caught? Maybe I am just overlooking something simple...help is appreciated. Thanks! Here is a fiddle to help out: http://jsfiddle.net/Nivaldo/FJ3qq/1/
I commented out the code that is not working. Also, another detail, it does not seem like the original code as i left it (except that i reduced the count of clusters and nodes) is actually handling the right number of distinct clusters. It should paint 4 different ones but is only painting with 3 colors.
The problem is that nodes is not the only data structure that needs to be initialised -- clusters needs to be as well. In particular, specific nodes are assigned to specific cluster indices. If you don't do that, things will break.
To fix, do something like
nodes.forEach(function(d) { clusters[d.cluster] = d; });
Complete jsfiddle here.
I'm using d3.js to make a simple line graph. I want to know if there's a way to create "holes" in the graph, that is, if the line can be interrupted or cut when there is no data available.
I'm looking into either delete the places I don't need from the domain, or setting the line weight to 0 in specific segments, but I can't find a way to do either of these.
Thanks for your help!
The D3 line generator has a built in function to do just this, line.defined. You can use this function to control where your line is defined and where it is not (like where you have missing data.) If you wanted to make your line undefined whenever the second value in the point array is a javascript NaN value, you could say:
line.defined(function(d) { return !isNaN(d[1]); });
Here is a good example of this in action.
I've got a basic Space Invaders type game going, and I can't get it to recognise when the shot from the player hits the alien. (I'm only checking Alien2 atm, the one second from the left). Since they're both moving, I've decided the only way to check for collisions is with either a range-based if statement (with 2 top coordinates and one left coordinate), or directly comparing the positions along the Y axis with Jquery.
I'm using the range-based solution at the moment, but so far it hasn't worked (not sure why).
My code so far:
if (key == "87"/*&& document.getElementById('BarrelOne').id=='BarrelOne'*/){
var Invader2 = document.getElementById('Alien2');
var Shot1 = document.getElementById('ShortShot');
Shot1.style.webkitAnimationPlayState="running";
setTimeout(function(){
Shot1.style.webkitAnimationPlayState="paused";
}, 1200);
if(document.elementFromPoint(625.5, 265.5) == Shot1){
Invader2.style.visibility="hidden";
}
};
Jsfiddle:
http://jsfiddle.net/ZJxgT/2/
I did something similar, and i found that it was much easier to achieve using gameQuery.
to test for collisions:
var collided = $("#div1").collision("#div2");
you can see full working example here
EDIT
If you're having trouble check out the API. For example, to find out how to use collisions check this part of the API.
the collision works in the following way:
This method returns the list of elements collisioning with the selected one but only those that match with the filter given as parameter. It takes two optional arguments (their order is not important). The filter is a string filtering element used to detect collision, it should contain all the elements the function should search collision into. For example if you look for collision with element of the class ‘foo’ that may be contained in a group you will use the filter ".group,.foo".
So, write something like this:
$("#ShortShot").collision("#Alien2").hide();
// will return the alien if it collides with ShortShot
or, to hide them both:
if (($("#ShortShot").collision("#Alien2")).length) {
$("#ShortShot").remove();
$("#Alien2").remove();
}
Instead of losing hours reinventing the wheel, I would suggest to switch (if still possible, depending on your time deadline) to a real 2D game engine for Javascript, with easy collision detection.
Check as well: 2D Engines for Javascript