Skip to content

Commit b5d9018

Browse files
committed
fixed logical operations for for 'if' and while
1 parent 6a27e1b commit b5d9018

File tree

3 files changed

+134
-30
lines changed

3 files changed

+134
-30
lines changed

index.html

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,15 @@
2929
<div class="container">
3030
<h4>JSPython development console</h4>
3131
<div id="editor">
32-
async def f1(p1, p2, p3, p4, p5):
33-
errorFunc(p1 or 1)
34-
errorFunc(p2 or 3)
35-
errorFunc(p3 or 6)
36-
errorFunc(p4 or 7)
37-
38-
"""
39-
l = null
40-
r = {price: 5}
41-
42-
if l?.price != null and r?.price != null:
43-
return 100
32+
x = 5
33+
y = 10
4434

45-
return 1
46-
"""
47-
f1()
35+
if x == 5 or y == 10:
36+
return 100
4837

38+
return 1
4939
</div>
50-
<!--
51-
def f(n):
52-
n * n
53-
x = [2, 3, 4]
54-
x.map(f)
55-
56-
# arr = [1,2,3]
57-
# arr.map(mapFunc)
58-
59-
-->
40+
6041
<button onclick="tokenize()">Tokenize</button>
6142
<button onclick="parse()">Parse</button>
6243
<button onclick="runInterpreter()">Run</button>

src/interpreter.spec.ts

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,119 @@ describe('Interpreter', () => {
483483
};
484484
expect(await e.evaluate(script, obj)).toContain(jsErrorMessage);
485485
expect(e.eval(script, obj)).toContain(jsErrorMessage);
486-
})
486+
});
487+
488+
it('if with AND', async () => {
489+
const script = `
490+
x=5
491+
y=10
492+
r = 0
493+
494+
if x == 5 and y == 10:
495+
r = x + y
496+
497+
return r
498+
`;
499+
500+
expect(await e.evaluate(script)).toBe(15);
501+
expect(e.eval(script)).toBe(15);
502+
}
503+
);
504+
505+
it('if with AND nullable objects', async () => {
506+
const script = `
507+
l = null
508+
r = {price: 5}
509+
510+
if l?.price != null and r?.price != null:
511+
return 100
512+
513+
return 1
514+
`;
515+
expect(await e.evaluate(script)).toBe(1);
516+
expect(e.eval(script)).toBe(1);
517+
}
518+
);
519+
520+
521+
it('if with AND in brackets', async () => {
522+
const script = `
523+
x=5
524+
y=10
525+
r = 0
526+
527+
if (x == 5) and (y == 10):
528+
r = x + y
529+
530+
return r
531+
`
532+
expect(await e.evaluate(script)).toBe(15);
533+
expect(e.eval(script)).toBe(15);
534+
}
535+
);
536+
537+
// incorrect
538+
it('passing value type to the arrow function', async () => {
539+
540+
const script = `
541+
x = [2,3,4,5,6,7,8,9]
542+
543+
sum = 0
544+
x.forEach(i => sum = sum + i)
545+
546+
sum
547+
`
548+
}
549+
);
550+
551+
it('passing value type to the for loop', async () => {
552+
553+
const script = `
554+
x = [2,3,4,5,6,7,8,9]
555+
sum = 0
556+
557+
for i in x:
558+
sum = sum + i
559+
560+
sum
561+
`
562+
expect(await e.evaluate(script)).toBe(44);
563+
expect(e.eval(script)).toBe(44);
564+
}
565+
);
566+
567+
it('passing value type to the while loop', async () => {
568+
569+
const script = `
570+
x = [2,3,4,5,6,7,8,9]
571+
sum = 0
572+
i=0
573+
while i < x.length:
574+
val = x[i]
575+
sum = sum + val
576+
i = i + 1
577+
578+
sum
579+
`
580+
expect(await e.evaluate(script)).toBe(44);
581+
expect(e.eval(script)).toBe(44);
582+
}
583+
);
584+
585+
it('passing value type to the arrow function', async () => {
586+
587+
const script = `
588+
x = [2,3,4,5,6,7,8,9]
589+
590+
sum = {value:0}
591+
x.forEach(i => sum.value = sum.value + i)
592+
593+
sum.value
594+
`
595+
expect(await e.evaluate(script)).toBe(44);
596+
expect(e.eval(script)).toBe(44);
597+
}
598+
);
487599

488600

489601
});

src/parser/parser.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,12 @@ export class Parser {
136136
}
137137

138138
const ifBody = getBody(instruction.tokens, endDefOfDef + 1);
139-
const conditionNode = this.createExpressionNode(instruction.tokens.slice(1, endDefOfDef))
139+
const conditionTokens = instruction.tokens.slice(1, endDefOfDef);
140+
141+
const conditionNode = (findIndexes(conditionTokens, OperationTypes.Logical, logicOpIndexes)) ?
142+
this.groupLogicalOperations(logicOpIndexes, conditionTokens)
143+
:
144+
this.createExpressionNode(conditionTokens);
140145

141146
let elseBody: AstNode[] | undefined = undefined;
142147
if (instructions.length > i + 1
@@ -261,10 +266,16 @@ export class Parser {
261266
throw (`Can't find : for [while]`)
262267
}
263268

264-
const condition = this.createExpressionNode(instruction.tokens.slice(1, endDefOfDef))
269+
270+
const conditionTokens = instruction.tokens.slice(1, endDefOfDef);
271+
const conditionNode = (findIndexes(conditionTokens, OperationTypes.Logical, logicOpIndexes)) ?
272+
this.groupLogicalOperations(logicOpIndexes, conditionTokens)
273+
:
274+
this.createExpressionNode(conditionTokens);
275+
265276
const body = getBody(instruction.tokens, endDefOfDef + 1);
266277

267-
ast.body.push(new WhileNode(condition, body, getTokenLoc(firstToken)))
278+
ast.body.push(new WhileNode(conditionNode, body, getTokenLoc(firstToken)));
268279

269280
} else if (getTokenValue(firstToken) === 'import') {
270281
let asIndex = findTokenValueIndex(instruction.tokens, v => v === 'as');
@@ -556,7 +567,7 @@ export class Parser {
556567
let name: AstNode | null = null;
557568
const namePart = keyValue[0];
558569

559-
if (namePart.length === 1) {
570+
if (namePart.length === 1) {
560571
name = new ConstNode(namePart[0]);
561572
} else if (getTokenValue(namePart[0]) === '['
562573
&& getTokenValue(namePart[namePart.length - 1]) === ']') {

0 commit comments

Comments
 (0)