@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
66 lines • 4.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.tryNormalizeFor = tryNormalizeFor;
const normalizer_data_1 = require("../../normalizer-data");
const parser_1 = require("../../../json/parser");
const normalize_meta_1 = require("../../normalize-meta");
const assert_1 = require("../../../../../../../util/assert");
const type_1 = require("../../../../model/type");
const normalize_single_node_1 = require("../structure/normalize-single-node");
const normalize_expressions_1 = require("../structure/normalize-expressions");
const normalize_symbol_1 = require("../values/normalize-symbol");
const normalize_comment_1 = require("../other/normalize-comment");
function tryNormalizeFor(data, [forToken, head, body]) {
// funny, for does not use top-level parenthesis
if (forToken.name !== type_1.RawRType.For) {
parser_1.parseLog.debug('encountered non-for token for supposed for-loop structure');
return undefined;
}
else if (head.name !== type_1.RawRType.ForCondition) {
throw new normalizer_data_1.ParseError(`expected condition for for-loop but found ${JSON.stringify(head)}`);
}
else if (body.name !== type_1.RawRType.Expression && body.name !== type_1.RawRType.ExprOfAssignOrHelp && body.name !== type_1.RawRType.LegacyEqualAssign) {
throw new normalizer_data_1.ParseError(`expected expr body for for-loop but found ${JSON.stringify(body)}`);
}
const newParseData = { ...data, data, currentRange: undefined, currentLexeme: undefined };
const { variable: parsedVariable, vector: parsedVector, comments } = normalizeForHead(newParseData, head.content);
const parseBody = (0, normalize_single_node_1.normalizeSingleNode)(newParseData, body);
if (parsedVariable === undefined ||
parsedVector === undefined ||
parseBody.type === type_1.RType.Delimiter) {
throw new normalizer_data_1.ParseError(`unexpected under-sided for-loop, received ${JSON.stringify([
parsedVariable,
parsedVariable,
parseBody,
])}`);
}
const { location, content } = (0, normalize_meta_1.retrieveMetaStructure)(forToken.content);
return {
type: type_1.RType.ForLoop,
variable: parsedVariable,
vector: parsedVector,
body: (0, normalize_meta_1.ensureExpressionList)(parseBody),
lexeme: content,
info: {
fullRange: data.currentRange,
additionalTokens: comments,
fullLexeme: data.currentLexeme,
},
location
};
}
function normalizeForHead(data, forCondition) {
// must have a child which is `in`, a variable on the left, and a vector on the right
const children = (0, normalize_meta_1.getWithTokenType)(forCondition.children);
const { comments, others } = (0, normalize_expressions_1.splitComments)(children);
const inPosition = others.findIndex(elem => elem.name === type_1.RawRType.ForIn);
(0, assert_1.guard)(inPosition > 0 && inPosition < others.length - 1, () => `for loop searched in and found at ${inPosition}, but this is not in legal bounds for ${JSON.stringify(children)}`);
const variable = (0, normalize_symbol_1.tryNormalizeSymbol)(data, [others[inPosition - 1]]);
(0, assert_1.guard)(variable !== undefined, () => `for loop variable should have been parsed to a symbol but was ${JSON.stringify(variable)}`);
(0, assert_1.guard)(variable.type === type_1.RType.Symbol, () => `for loop variable should have been parsed to a symbol but was ${JSON.stringify(variable)}`);
const vector = (0, normalize_expressions_1.normalizeExpressions)(data, [others[inPosition + 1]]);
(0, assert_1.guard)(vector.length === 1 && vector[0].type !== type_1.RType.Delimiter, () => `for loop vector should have been parsed to a single element but was ${JSON.stringify(vector)}`);
const parsedComments = comments.map(c => (0, normalize_comment_1.normalizeComment)(data, c.content));
return { variable, vector: vector[0], comments: parsedComments };
}
//# sourceMappingURL=normalize-for.js.map