Skip to content

Commit 865d452

Browse files
committed
#39 skipping last commas in JSON
1 parent 86a41fc commit 865d452

File tree

5 files changed

+25
-15
lines changed

5 files changed

+25
-15
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jspython-interpreter",
3-
"version": "2.1.14",
3+
"version": "2.1.15",
44
"description": "JSPython is a javascript implementation of Python language that runs within web browser or NodeJS environment",
55
"keywords": [
66
"python",

src/interpreter.spec.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ describe('Interpreter', () => {
132132
expect(e.eval("x = {['m'+1]: 1+2*3}\nx.m1")).toBe(7);
133133
});
134134

135+
it('json ignore last comma', () => {
136+
expect(JSON.stringify(e.eval('[{a:1,}, {a:2},]'))).toBe(JSON.stringify([{ a: 1, }, { a: 2 },]));
137+
});
138+
139+
[{ a: 1 }, { a: 2 }];
140+
135141
it('json with dynamic key', () => {
136142
expect(e.eval("p = 'prop'\nx = {[p + '_'+1]: 1+2*3}\nx.prop_1")).toBe(7);
137143
expect(e.eval("p = {x:'prop'}\nx = {[p.x + '_'+1]: 1+2*3}\nx.prop_1")).toBe(7);
@@ -296,7 +302,6 @@ describe('Interpreter', () => {
296302
expect(e.eval(script, {}, ['times', 2, 3])).toBe(6);
297303
});
298304

299-
300305
it('long comments issue', () => {
301306
const script = `
302307
async def f2():
@@ -988,7 +993,7 @@ describe('Interpreter', () => {
988993
`;
989994
expect(await interpreter.evalAsync(script)).toBe(11);
990995
expect(interpreter.eval(script)).toBe(11);
991-
});
996+
});
992997

993998
//
994999
});

src/interpreter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export class Interpreter {
221221
return scripts.indexOf(`def ${funcName}`) > -1;
222222
}
223223

224-
private assignImportContext(
224+
assignImportContext(
225225
ast: AstBlock,
226226
context: Record<string, unknown>
227227
): Record<string, unknown> {

src/interpreter.v1.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,13 +1384,13 @@ describe('Interpreter', () => {
13841384
it('JSON parsing last comma error', async () => {
13851385
let x = '';
13861386
try {
1387-
await e.evaluate(`[[12, 42],`);
1387+
await e.evaluate(`[[12, 42],]`);
13881388
x = 'NO ERROR';
13891389
} catch (error) {
13901390
x = 'ERROR';
13911391
}
13921392

1393-
expect(x).toBe('ERROR');
1393+
expect(x).toBe('NO ERROR');
13941394

13951395
x = '';
13961396
try {
@@ -1401,7 +1401,7 @@ describe('Interpreter', () => {
14011401
} catch (error) {
14021402
x = 'ERROR';
14031403
}
1404-
expect(x).toBe('ERROR');
1404+
expect(x).toBe('NO ERROR');
14051405

14061406
x = '';
14071407
try {

src/parser/parser.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,22 +204,24 @@ export class Parser {
204204
instructions.length > i + 1 &&
205205
getTokenValue(instructions[i + 1].tokens[0]) === 'elif'
206206
) {
207-
208207
const elifInstruction = instructions[++i];
209208

210209
const endOfElif = findTokenValueIndex(elifInstruction.tokens, v => v === ':');
211210

212211
const conditionTokens = elifInstruction.tokens.slice(1, endDefOfDef);
213212

214-
const elifConditionNode = findIndexes(conditionTokens, OperationTypes.Logical, logicOpIndexes)
213+
const elifConditionNode = findIndexes(
214+
conditionTokens,
215+
OperationTypes.Logical,
216+
logicOpIndexes
217+
)
215218
? this.groupLogicalOperations(logicOpIndexes, conditionTokens)
216219
: this.createExpressionNode(conditionTokens);
217-
218-
const elifBody = getBody(elifInstruction.tokens, endOfElif+1);
220+
221+
const elifBody = getBody(elifInstruction.tokens, endOfElif + 1);
219222
elifNodes.push(
220223
new ElifNode(elifConditionNode, elifBody, getTokenLoc(elifInstruction.tokens[0]))
221224
);
222-
223225
}
224226

225227
// else
@@ -690,6 +692,9 @@ export class Parser {
690692
const keyValueTokens = splitTokens(tokens.splice(1, tokens.length - 2), ',');
691693
const props = [] as ObjectPropertyInfo[];
692694
for (let i = 0; i < keyValueTokens.length; i++) {
695+
if (!keyValueTokens[i].length) {
696+
continue;
697+
}
693698
const keyValue = splitTokens(keyValueTokens[i], ':');
694699
if (keyValue.length === 1) {
695700
const pInfo = {
@@ -731,9 +736,9 @@ export class Parser {
731736

732737
// create Array Node
733738
if (getTokenValue(tokens[0]) === '[' && getTokenValue(tokens[tokens.length - 1]) === ']') {
734-
const items = splitTokens(tokens.splice(1, tokens.length - 2), ',').map(tkns =>
735-
this.createExpressionNode(tkns)
736-
);
739+
const items = splitTokens(tokens.splice(1, tokens.length - 2), ',')
740+
.filter(tkns => tkns?.length)
741+
.map(tkns => this.createExpressionNode(tkns));
737742

738743
return new CreateArrayNode(items, getTokenLoc(tokens[0]));
739744
}

0 commit comments

Comments
 (0)