Skip to content

Commit 386784b

Browse files
committed
added While loop
1 parent 266c85a commit 386784b

File tree

5 files changed

+56
-8
lines changed

5 files changed

+56
-8
lines changed

index.html

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
<h4>JSPython development console</h4>
3131
<div id="editor">
3232
sum = 0
33-
34-
for item in [1,2,3]:
35-
sum = sum + item
33+
i = 0
34+
35+
while i<1000:
36+
sum = sum + i
37+
i = i + 1
3638

3739
sum
3840

@@ -94,7 +96,11 @@ <h4>JSPython development console</h4>
9496
try {
9597
const scope = {
9698
Math,
97-
print: (p1, p2) => { return p1; },
99+
dateTime: () => new Date(),
100+
print: (p1, p2) => {
101+
console.log(p1);
102+
return p1;
103+
},
98104
x: 10,
99105
o: {
100106
f1: (x, y) => { return { x, y }; },

src/common/ast-types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export abstract class AstNode {
99
| 'getSingleVar' | 'setSingleVar' | 'dotObjectAccess' | 'bracketObjectAccess'
1010
| 'funcCall' | 'funcDef' | 'arrowFuncDef'
1111
| 'createObject' | 'createArray'
12-
| 'if' | 'for' | 'tryCatch'
12+
| 'if' | 'for' | 'while'
1313
| 'return' | 'continue' | 'break'
1414
) { }
1515
}
@@ -88,6 +88,12 @@ export class ForNode extends AstNode {
8888
}
8989
}
9090

91+
export class WhileNode extends AstNode {
92+
constructor(public condition: AstNode, public body: AstNode[]) {
93+
super('while');
94+
}
95+
}
96+
9197
export class GetSingleVarNode extends AstNode {
9298
name: string;
9399
nullCoelsing: boolean | undefined = undefined;

src/evaluator/evaluator.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
22
ArrowFuncDefNode,
33
AssignNode, AstBlock, AstNode, BinOpNode, BracketObjectAccessNode, ConstNode, CreateArrayNode,
4-
CreateObjectNode, DotObjectAccessNode, ForNode, FunctionCallNode, FunctionDefNode, GetSingleVarNode, IfNode, OperationFuncs, Primitive, SetSingleVarNode
4+
CreateObjectNode, DotObjectAccessNode, ForNode, FunctionCallNode, FunctionDefNode, GetSingleVarNode, IfNode, OperationFuncs, Primitive, SetSingleVarNode, WhileNode
55
} from '../common';
66
import { Scope } from './scope';
77

@@ -110,6 +110,16 @@ export class Evaluator {
110110
return;
111111
}
112112

113+
if (node.type === 'while') {
114+
const forNode = node as WhileNode;
115+
const newScope = scope;
116+
117+
while(this.evalNode(forNode.condition, newScope)){
118+
this.evalBlock({ body: forNode.body } as AstBlock, newScope);
119+
}
120+
121+
return;
122+
}
113123

114124
if (node.type === "const") {
115125
return (node as ConstNode).value;

src/interpreter.spec.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ describe('Interpreter', () => {
209209

210210

211211
it('if condition', () => {
212-
const script = (p: ) => `
212+
const script = (p: number) => `
213213
x = 1
214214
if x == ${p}:
215215
x = 5
@@ -240,5 +240,18 @@ describe('Interpreter', () => {
240240
expect(e.evaluate(script)).toBe(6);
241241
});
242242

243+
it('simple while', () => {
244+
const script = `
245+
sum = 0
246+
i = 0
247+
248+
while i < 5:
249+
sum = sum + i
250+
i = i + 1
251+
252+
sum
253+
`;
254+
expect(e.evaluate(script)).toBe(10);
255+
});
243256

244257
});

src/parser/parser.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
BinOpNode, ConstNode, AstBlock, Token, ParserOptions, AstNode, Operators, AssignNode, TokenTypes,
33
GetSingleVarNode, FunctionCallNode, getTokenType, getTokenValue, isTokenTypeLiteral, getStartLine,
44
getStartColumn, getEndColumn, getEndLine, findOperators, splitTokens, DotObjectAccessNode, BracketObjectAccessNode,
5-
findTokenValueIndex, FunctionDefNode, CreateObjectNode, ObjectPropertyInfo, CreateArrayNode, ArrowFuncDefNode, ExpressionOperators, IfNode, ForNode
5+
findTokenValueIndex, FunctionDefNode, CreateObjectNode, ObjectPropertyInfo, CreateArrayNode, ArrowFuncDefNode, ExpressionOperators, IfNode, ForNode, WhileNode
66
} from '../common';
77

88
export class InstructionLine {
@@ -125,6 +125,19 @@ export class Parser {
125125

126126
ast.body.push(new ForNode(sourceArray, itemVarName, forBody))
127127

128+
} else if (getTokenValue(instruction.tokens[0]) === 'while') {
129+
130+
const endDefOfDef = findTokenValueIndex(instruction.tokens, v => v === ':');
131+
132+
if (endDefOfDef === -1) {
133+
throw (`Can't find : for [while]`)
134+
}
135+
136+
const condition = this.createExpressionNode(instruction.tokens.slice(1, endDefOfDef))
137+
const body = getBody(instruction.tokens, endDefOfDef + 1);
138+
139+
ast.body.push(new WhileNode(condition, body))
140+
128141
} else if (assignTokens.length > 1) {
129142
const target = this.createExpressionNode(assignTokens[0]);
130143
const source = this.createExpressionNode(assignTokens[1]);

0 commit comments

Comments
 (0)