From 3447059f1145550465ecbe10c5d6e82420d5a823 Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 29 Dec 2016 14:45:30 -0800 Subject: [PATCH] refactor: introduce a `Loop` node type (#105) BREAKING CHANGE: Rather than a `While` node with a virtual condition and null for other properties, this introduces a new `Loop` node that only has a body. --- src/parser.js | 19 +++++++++----- test/examples/loop/output.json | 48 ++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/parser.js b/src/parser.js index 105968bf..502b9c18 100644 --- a/src/parser.js +++ b/src/parser.js @@ -10,7 +10,7 @@ import lex, { SourceType } from 'coffee-lex'; import locationsEqual from './util/locationsEqual'; import locationContainingNodes from './util/locationContainingNodes'; import locationWithLastPosition from './util/locationWithLastPosition'; -import makeNode, { Bool, RegexFlags } from './nodes'; +import makeNode, { RegexFlags } from './nodes'; import mapAny from './mappers/mapAny'; import mapLiteral from './mappers/mapLiteral'; import mergeLocations from './util/mergeLocations'; @@ -653,16 +653,23 @@ function convert(context) { } case 'While': { - const result = makeNode(context, 'While', locationContainingNodes(node, node.condition, node.body), { + let start = linesAndColumns.indexForLocation({ line: node.locationData.first_line, column: node.locationData.first_column }); + let tokens = context.sourceTokens; + let startTokenIndex = tokens.indexOfTokenContainingSourceIndex(start); + let startTokenType = tokens.tokenAtIndex(startTokenIndex).type; + + if (startTokenType === SourceType.LOOP) { + return makeNode(context, 'Loop', locationContainingNodes(node, node.body), { + body: convertChild(node.body) + }); + } + + return makeNode(context, 'While', locationContainingNodes(node, node.condition, node.body), { condition: convertChild(node.condition), guard: convertChild(node.guard), body: convertChild(node.body), isUntil: node.condition.inverted === true }); - if (result.raw.indexOf('loop') === 0) { - result.condition = Bool.true(); - } - return result; } case 'Existence': diff --git a/test/examples/loop/output.json b/test/examples/loop/output.json index 3a4e7f57..c9b221d8 100644 --- a/test/examples/loop/output.json +++ b/test/examples/loop/output.json @@ -2,47 +2,55 @@ "type": "Program", "line": 1, "column": 1, - "range": [ 0, 8 ], + "range": [ + 0, + 8 + ], "raw": "loop\n a", "body": { "type": "Block", "line": 1, "column": 1, - "range": [ 0, 8 ], - "raw": "loop\n a", + "range": [ + 0, + 8 + ], "statements": [ { - "type": "While", + "type": "Loop", "line": 1, "column": 1, - "range": [ 0, 8 ], - "raw": "loop\n a", - "isUntil": false, - "guard": null, + "range": [ + 0, + 8 + ], "body": { "type": "Block", "line": 2, "column": 3, - "range": [ 7, 8 ], - "raw": "a", - "inline": false, + "range": [ + 7, + 8 + ], "statements": [ { "type": "Identifier", "line": 2, "column": 3, - "range": [ 7, 8 ], + "range": [ + 7, + 8 + ], "raw": "a", "data": "a" } - ] + ], + "raw": "a", + "inline": false }, - "condition": { - "type": "Bool", - "data": true, - "virtual": true - } + "raw": "loop\n a" } - ] + ], + "raw": "loop\n a" } -} \ No newline at end of file +}