CodeMirror overlay that counts parenthesis - javascript

UPDATE:
I made a fix to the code so it looks like this:
var ch;
if (state.inExpression) {
while ((ch = stream.next()) != null) {
if (ch == "(") {
depth++;
} else if (ch == ")") {
depth--;
if (depth === 0) {
state.inExpression = false;
}
}
return highlightClass;
}
} else {
if (stream.match("#if")) {
state.inExpression = true;
return highlightClass;
}
}
It works, except if I make a change to the line of code I want highlighted.
I printed to the console and got the following:
What seems to be happening is before the overlay code is finished parsing, when I make a change to the file the code is interrupted and restarted. The problem is that the depth counter never was reset so the parentheses count gets messed up.
How can I make sure my loop will run uninterrupted? Or is there a different solution?
Original Question:
I am trying to write a CodeMirror Overlay to highlight Laravel syntax. An example of syntax to be highlighted would be #if (foo(bar)). The highlighting should start at the # and end after the last ), thus it is necessary to count parenthesis.
The following is the code I wrote to achieve this, but it is not working properly.
var ch;
if (state.inExpression) {
while ((ch = stream.next()) != null) {
if (ch == "(") {
depth++;
return highlightClass;
} else if (ch == ")") {
depth--;
if (depth === 0) {
state.inExpression = false;
return highlightClass;
}
}
}
} else {
if (stream.match("#if")) {
state.inExpression = true;
return highlightClass;
}
}
The results are hard to describe, so just take a look at this screenshot:
But it seems that my code also messes up the 'matching bracket' feature that is built in.
I think for some reason I am not properly exiting the state.inExpression.
Any ideas?

Related

is there a way to make a generic if condition to expand my steps easily?

iam new on React and have a Project where i have to implement a react joyride tour into a finished tool.
currently i have this if condition to check on which page iam, to set the right steps.
if (this.props.location.pathname === '/') {
steps = []
} else if (this.props.location.pathname === '/matches/' || this.props.location.pathname === '/matches') {
if (this.props.firstPartClicked === true) {
steps = matchSiteStepsOne
} else if (this.props.secondPartClicked === true) {
steps = matchSiteStepsTwo
} else {
steps = matchSiteSteps
}
} else if (this.props.location.pathname.startsWith('/matches/') && this.props.location.pathname.endsWith('/edit/') && this.props.location.pathname.match('\\d+')) {
if (this.props.firstPartClicked === true) {
steps = matchEditorStepsOne
} else if (this.props.secondPartClicked === true) {
steps = matchEditorStepsTwo
} else {
steps = matchEditorSteps
}
} else if (this.props.location.pathname.startsWith('/matches/') && this.props.location.pathname.includes('sequence')) {
if (this.props.firstPartClicked === true) {
steps = matchSequenceStepsOne
} else if (this.props.secondPartClicked === true) {
steps = matchSequenceStepsTwo
} else {
steps = matchSequenceSteps
}
} else if (this.props.location.pathname.startsWith('/matches/') && this.props.location.pathname.match('\\d+')) {
steps = matchSteps
}
now my question is if is there a way to make it more generic so i can easily expand more steps on different pages, without so much redundant code?
You can reduce redundant code a little by only looking up pathname once, and storing it in a variable as in
pathname = this.props.location.pathname
This should make your if statements a bit shorter and easier to read. You could also deduplicate some code if e.g. you replaced matchSiteSteps with matchSteps['Site'], and called a function three times with a body like:
if (this.props.firstPartClicked === true) {
steps = matchStepsOne[type]
} else if (this.props.secondPartClicked === true) {
steps = matchStepsTwo[type]
} else {
steps = matchSteps[type]
}
}

Subclass Variables are Undefined - js

I am programming a game and am having trouble with variables and inheritance, whenever I try to access them in the inherited class they come up as undefined. I have tried using super to help with the problem but that has not worked, this may be because I am relatively new to JavaScript.
The variables work in the base class but do not work in the subclass.
This is the inherited class
This is the Base Class.
Just to clarify the question I am asking why the variables come up as undefined in the subclass but not in the base class and how I can fix this. Thanks!
The code is clearer in the pictures.
class charachter {
constructor(xPos, yPos) {
this.rightVelocity = 0;
this.leftVelocity = 0;
this.upVelocity = 0;
this.downVelocity = 0;
this.xyCordsRaw = [xPos, yPos];
this.xyCordsBlock = [Math.round(this.xyCordsRaw[0] / 50),
Math.round(this.xyCordsRaw[1] / 100)
]
}
updateCharachter() {
ctx.drawImage(charachterRight, this.xyCordsRaw[0],
this.xyCordsRaw[1])
}
findTileStandingOnType() {
return
solidObjects.includes(biome[this.xyCordsBlock[1] + 1][this.xyCordsBlock[0]])
}
isOnTheGround() {
return this.findTileStandingOnType() == true &&
this.xyCordsRaw[1] == (this.xyCordsBlock[1] * 100) + 25
}
isTileAbove() {
return solidObjects.includes(biome[this.xyCordsBlock[1] - 1]
[this.xyCordsBlock[0]])
}
isTouchingTileAbove() {
return this.isTileAbove() == true && this.xyCordsBlock[1] * 100 == this.xyCordsRaw[1]
}
isWallLeft() {
return solidObjects.includes(biome[this.xyCordsBlock[1]][this.xyCordsBlock[0] - 1])
}
isWallRight() {
return solidObjects.includes(biome[this.xyCordsBlock[1]][this.xyCordsBlock[0] + 1])
}
isTouchingWallRight() {
return this.isWallRight() == true && this.xyCordsBlock[0] * 50 == this.xyCordsRaw[0]
}
isTouchingWallLeft() {
return this.isWallLeft() == true && this.xyCordsBlock[0] * 50 == this.xyCordsRaw[0]
}
}
class playerChar extends charachter {
constructor(xPos, yPos, leftVelocity, rightVelocity, upVelocity, downVelocity, xyCordsRaw, xyCordsBlock) {
super(xPos, yPos, leftVelocity, rightVelocity, upVelocity, downVelocity, xyCordsRaw, xyCordsBlock);
document.addEventListener('keydown', this.takeInput);
}
takeInput(e) {
if (e.code == 'KeyA') {
console.log(this.leftVelocity);
}
if (e.code == 'KeyW') {
console.log("The letter W was pressed");
}
if (e.code == 'KeyD') {
console.log(this.xyCordsRaw);
}
}
}
var player = new playerChar(150, 325);
The immediate problem that presents itself is the use of this in event listeners.
document.addEventListener('keydown', this.takeInput);
passes a reference to the takeInput function object when calling addEventListener, and because it's an event handler of document, takeInput will have a this value of document when called. Try
document.addEventListener('keydown', this.takeInput.bind(this));
to begin with to see what difference it makes.
The next error to correct is to the line feed after return in
findTileStandingOnType(){
return
solidObjects.includes(biome[this.xyCordsBlock[1]
This should be
findTileStandingOnType(){
return solidObjects.includes(biome[this.xyCordsBlock[1] + 1][this.xyCordsBlock[0]])}
Return statements without a semi-colon separator only continue on the next line if it would be a syntax error if they didn't. That is not the
case here.

javascript recursive function does not stop execution

Inside of my progress function, it will hit the base of the recursion, but the value im expecting to have returned does not change.
let graph = [[1,1,1],[1,1,1,],[1,1,1]]
function findPath(graph){
function progress(row, col){
if(row == graph.length-1 && graph[row][col]== 1) {
console.log('makes it here but does not return true !?')
return true;
}
//check right
if(graph[row][col+1] == 1) {
graph[row][col] = 2
progress(row, col+1);
}
// check left
if(graph[row][col-1] == 1) {
graph[row][col] = 2
progress(row, col-1);
}
// check down
if(graph[row+1][col] == 1){
graph[row][col] = 2
progress(row+1, col)
}
}
for(let i = 0; i < graph[0].length; i++) {
if(graph[0][i] == 1) {
if(progress(0, i)) {
return true;
}
}
}
return false;
}
console.log(findPath(graph))
This should return true, it hits the condition (logs the text) but then keeps moving, and always returns false.
Ok, recursion works with an stack, each call is stacked and just continues your execution after all the other call stacked after are done.
Like:
call1 -> call2 -> call3 -> callN
after reach the last call (callN), all the calls will be unstacket from back to front.
You just return true on the last call, but this value get lost when the function calls is unstacked
In other words, to your example works, you need to always return the value from the progress function.
I tried to adapty your code to work better:
let graph = [[1,1,1],[1,1,1,],[1,1,1]]
function findPath(graph){
function progress(row, col){
if(row == graph.length-1 && graph[row][col]== 1) {
return true;
}
//check right
if(graph[row][col+1] == 1) {
graph[row][col] = 2
var right = progress(row, col+1);
}
// check left
if(graph[row][col-1] == 1) {
graph[row][col] = 2
var left = progress(row, col-1);
}
// check down
if(graph[row+1][col] == 1){
graph[row][col] = 2
var down = progress(row+1, col)
}
// propagate result
return (right || left || down)
}
for(let i = 0; i < graph[0].length; i++) {
if(graph[0][i] == 1) {
if(progress(0, i)) {
return true;
}
}
}
return false;
}
console.log(findPath(graph))
I only look to the recursion part, and not for the problem it self, in my example, if in any path (right, left or down) i grab that value and pass back untill it reach my first function call. That way, the true value will be propagate until the end
Hope i have helped

Javascript Testing Corners of an Array (Grid)

I'm doing this project trying to reproduce Schelling's Segregation model. I have a function(below) that is testing to see if the four immediate adjacent cells of the array are either the same or different or empty compared to the current cell being tested.
There are four possible spots to be tested for every cell in the array. But on corners and side spots, obviously you cant test spaces that are out of bounds. So in the function, if it finds one of the out of bounds spaces it decrements the number total around the cell. However, it keeps crashing telling me that I have an Uncaught Reference Error: Cannot read property '0' of undefined. I can't tell why its crashing.
The final lines of this code take the number of goods(similar cells) and the total number of cells around it (empty cells do not count) and gets a percentage similar.
Any help would be appreciated into telling me why it might be crashing and giving me an error? Thanks!
model.Test = function( i, j )
{
var numberToTest= 4;
var goods= 0;
if ((i - 1) >= 0)
{
if (model.BoardArray[i-1][j] != "E")
{
if (model.BoardArray[i][j] == model.BoardArray[i-1][j])
{
goods++;
}
}
else
{
numberToTest--;
}
}
else
{
numberToTest--;
}
if((i + 1) < $("#BoardSizeValue").val())
{
if (model.BoardArray[i+1][j] != "E")
{
if (model.BoardArray[i][j] == model.BoardArray[i+1][j])
{
goods++;
}
}
else
{
numberToTest--;
}
}
else
{
numberToTest--;
}
if ((j - 1) >= 0)
{
if (model.BoardArray[i][j-1] != "E")
{
if (model.BoardArray[i][j] == model.BoardArray[i][j-1])
{
goods++;
}
}
else
{
numberToTest--;
}
}
else
{
numberToTest--;
}
if ((j + 1) < $("#BoardSizeValue").val())
{
if (model.BoardArray[i][j+1] != "E")
{
if (model.BoardArray[i][j] == model.BoardArray[i][j+1])
{
goods++;
}
}
else
{
numberToTest--;
}
}
else
{
numberToTest--;
}
var similar = $("#SimilarSlider").val()/100;
if (numberToTest == 0)
{
return false;
}
else
{
var needed = goods/numberToTest;
if (needed >= similar)
{
return false;
}
else
{
return true;
}
}
}
From looking at your code, you would only get a Reference Error: Cannot read property '0' of undefined. if i was out of the bounds of the array.
I think the problem might be in this part of the code:
if ((i - 1) >= 0) {
if (model.BoardArray[i-1][j] != "E") {
if (model.BoardArray[i][j] == model.BoardArray[i-1][j]) {
if i = $("#BoardSizeValue").val() and $("#BoardSizeValue").val() is a one-based index of the array size, then [i-1] would be okay, but not [i]. So try adjusting your code to this:
if ((i - 1) >= 0 && i < $("#BoardSizeValue").val()) {
if (model.BoardArray[i-1][j] != "E") {
if (model.BoardArray[i][j] == model.BoardArray[i-1][j]) {
This would also apply to the j comparisons as well.

"else if" statement within for loop within larger if/else if/else statement

Is it possible to do something like this in JavaScript?
if (name == 'foo') {
exampleFunction('some_arg');
}
else if (name == 'bar') {
exampleFunction('another_arg');
}
for (i in exampleObject) {
else if (name == exampleObject[i].name) {
exampleFunction(exampleObject[i].arg);
}
}
else {
exampleFunction('default')
}
I tried it, but got an "unexpected keyword else on line 8" (the "else if" within the for loop). Is there another way to do this?
edit: updated this to use exampleObject[i] in the loop. My bad!
No. I think the best way to accomplish this is to move the for loop into an else block and do the following
if (name == 'foo') {
exampleFunction('some_arg');
}
else if (name == 'bar') {
exampleFunction('another_arg');
}
else {
var isFound = false;
for (i in exampleObject) {
if (name == exampleObject.name) {
exampleFunction(exampleObject.arg);
isFound = true;
}
}
if (!isFound) {
exampleFunction('default')
}
}
Note: It looks like there are other errors in this code. The for loop declares the i iteration variable but never actually uses it. Did you mean for the if check in the for loop to use i instead of name?
if (name == 'foo') {
exampleFunction('some_arg');
}
else if (name == 'bar') {
exampleFunction('another_arg');
}
else {
var isFound = false;
for (i in exampleObject) {
if (name == exampleObject.name) {
exampleFunction(exampleObject.arg);
isFound = true;
break;
}
}
if (!isFound) {
exampleFunction('default')
}
}
Here is the correct solution. It short circuts the if statements in the loop just like else if would short circuit. This is the same solution as #1 but it correctly short circuits.
The following code looks wrong to me , have the for loop inside if block
for (i in exampleObject) {
else if (name == exampleObject.name) {
exampleFunction(exampleObject.arg);
}
that is not possible. I would try an come up with a better example to show you how to do what you want, but honestly I am not sure what you want to do. The for loop is confusing me. Can you provide some more information?
In a word, no. You are terminating the if-statement block with the last brace before the for statement.
Well for one, shouldn't this:
for (i in exampleObject) {
else if (name == exampleObject.name) {
exampleFunction(exampleObject.arg);
}
}
be this:
for (i in exampleObject) {
else if (name == i.name) {
exampleFunction(i.arg);
}
}
Though i don't know much (if anything) about js, this is just a guess at something that isn't even the problem you're talking about.
Would you be adverse to doing it like this:
bit = 0;
if (name == 'foo') {
exampleFunction('some_arg');
}
else if (name == 'bar') {
exampleFunction('another_arg');
}
else {
bit = 1;
}
bit2 = 0;
while(bit == 1){
for (i in exampleObject) {
if (name == i.name) {
exampleFunction(i.arg);
bit = 0
bit2 = 1;
}
}
}
if(bit2 = 0){
exampleFunction('default');
}
?
Something like this may help?
found = false
if (name == 'foo') {
found = true
exampleFunction('some_arg');
}
else if (name == 'bar') {
found = true
exampleFunction('another_arg');
}
else {
for (i in exampleObject) {
if (name == i.name) {
exampleFunction(i.arg);
found = true
break;
}
}
}
if !found:
exampleFunction('default')

Categories