Skip to content

Commit 09a1ce4

Browse files
Copilotmathiasrw
andauthored
Implement BREAK/CONTINUE and LEAVE/ITERATE statements to fix #37 (#2263)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mathiasrw <[email protected]> Co-authored-by: Mathias Wulff <[email protected]>
1 parent 9cbd192 commit 09a1ce4

File tree

4 files changed

+482
-267
lines changed

4 files changed

+482
-267
lines changed

src/69while.js

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
/*
22
//
3-
// CREATE VIEW for Alasql.js
3+
// WHILE, BREAK, CONTINUE, and BEGIN...END for Alasql.js
44
// Date: 03.11.2014
55
// (c) 2014, Andrey Gershun
66
//
77
*/
88

9+
// Control flow exception types for BREAK and CONTINUE statements
10+
function createControlFlowException(name) {
11+
var Exception = function () {
12+
this.message = name;
13+
};
14+
Exception.prototype = Object.create(Error.prototype);
15+
Exception.prototype.constructor = Exception;
16+
return Exception;
17+
}
18+
19+
yy.BreakException = createControlFlowException('BREAK');
20+
yy.ContinueException = createControlFlowException('CONTINUE');
21+
922
yy.While = function (params) {
1023
return Object.assign(this, params);
1124
};
@@ -41,8 +54,18 @@ yy.While.prototype.execute = function (databaseid, params, cb) {
4154
loop();
4255
} else {
4356
while (fn(params, alasql)) {
44-
var res1 = self.loopstat.execute(databaseid, params);
45-
res.push(res1);
57+
try {
58+
var res1 = self.loopstat.execute(databaseid, params);
59+
res.push(res1);
60+
} catch (err) {
61+
if (err instanceof yy.BreakException) {
62+
break;
63+
} else if (err instanceof yy.ContinueException) {
64+
continue;
65+
} else {
66+
throw err;
67+
}
68+
}
4669
}
4770
}
4871
return res;
@@ -57,9 +80,7 @@ yy.Break.prototype.toString = function () {
5780
};
5881

5982
yy.Break.prototype.execute = function (databaseid, params, cb, scope) {
60-
var res = 1;
61-
if (cb) res = cb(res);
62-
return res;
83+
throw new yy.BreakException();
6384
};
6485

6586
yy.Continue = function (params) {
@@ -71,9 +92,7 @@ yy.Continue.prototype.toString = function () {
7192
};
7293

7394
yy.Continue.prototype.execute = function (databaseid, params, cb, scope) {
74-
var res = 1;
75-
if (cb) res = cb(res);
76-
return res;
95+
throw new yy.ContinueException();
7796
};
7897

7998
yy.BeginEnd = function (params) {
@@ -88,15 +107,24 @@ yy.BeginEnd.prototype.execute = function (databaseid, params, cb, scope) {
88107
var self = this;
89108
var res = [];
90109

91-
var idx = 0;
92-
runone();
93-
function runone() {
94-
self.statements[idx].execute(databaseid, params, function (data) {
95-
res.push(data);
96-
idx++;
97-
if (idx < self.statements.length) return runone();
98-
if (cb) res = cb(res);
99-
});
110+
if (cb) {
111+
// Asynchronous execution with callback
112+
var idx = 0;
113+
runone();
114+
function runone() {
115+
self.statements[idx].execute(databaseid, params, function (data) {
116+
res.push(data);
117+
idx++;
118+
if (idx < self.statements.length) return runone();
119+
if (cb) res = cb(res);
120+
});
121+
}
122+
} else {
123+
// Synchronous execution
124+
for (var i = 0; i < self.statements.length; i++) {
125+
var res1 = self.statements[i].execute(databaseid, params);
126+
res.push(res1);
127+
}
100128
}
101129
return res;
102130
};

src/alasqlparser.jison

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,12 @@ DATABASE(S)? return 'DATABASE'
159159
'INTERSECT' return 'INTERSECT'
160160
'INTERVAL' return 'INTERVAL'
161161
'INTO' return 'INTO'
162+
'ITERATE' return 'ITERATE'
162163
'JOIN' return 'JOIN'
163164
'KEY' return 'KEY'
164165
'LAST' return 'LAST'
165166
'LET' return 'LET'
167+
'LEAVE' return 'LEAVE'
166168
'LEFT' return 'LEFT'
167169
'LIKE' return 'LIKE'
168170
'LIMIT' return 'LIMIT'
@@ -2623,11 +2625,15 @@ While
26232625
Continue
26242626
: CONTINUE
26252627
{ $$ = new yy.Continue(); }
2628+
| ITERATE
2629+
{ $$ = new yy.Continue(); }
26262630
;
26272631

26282632
Break
26292633
: BREAK
26302634
{ $$ = new yy.Break(); }
2635+
| LEAVE
2636+
{ $$ = new yy.Break(); }
26312637
;
26322638

26332639
BeginEnd

0 commit comments

Comments
 (0)