Skip to content

Commit

Permalink
Support for complex structs (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
worksofliam committed Feb 9, 2022
1 parent 8d2f479 commit b5ea11a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 23 deletions.
64 changes: 41 additions & 23 deletions src/language/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ module.exports = class Parser {
/** @type {Cache[]} */
let scopes = [];

/** @type {Declaration[]} Free format struct scopes. Used for free-format only */
let dsScopes = [];

// Global scope bits
scopes.push(new Cache());

Expand Down Expand Up @@ -389,36 +392,40 @@ module.exports = class Parser {

case `DCL-DS`:
if (currentItem === undefined) {
if (!parts.includes(`TEMPLATE`)) {
currentItem = new Declaration(`struct`);
currentItem.name = partsLower[1];
currentItem.keywords = parts.slice(2);
currentItem.description = currentDescription.join(` `);
currentItem.tags = currentTags;

currentItem.position = {
path: file,
line: lineNumber
}
currentItem = new Declaration(`struct`);
currentItem.name = partsLower[1];
currentItem.keywords = parts.slice(2);
currentItem.description = currentDescription.join(` `);
currentItem.tags = currentTags;

currentGroup = `structs`;
// Does the keywords include a keyword that makes end-ds useless?
if (currentItem.keywords.some(keyword => oneLineTriggers[`DCL-DS`].some(trigger => keyword.startsWith(trigger)))) {
scope.structs.push(currentItem);
resetDefinition = true;
} else {
currentItem.readParms = true;
}
currentItem.position = {
path: file,
line: lineNumber
}

currentDescription = [];
currentGroup = `structs`;
// Does the keywords include a keyword that makes end-ds useless?
if (currentItem.keywords.some(keyword => oneLineTriggers[`DCL-DS`].some(trigger => keyword.startsWith(trigger)))) {
scope.structs.push(currentItem);
} else {
currentItem.readParms = true;
dsScopes.push(currentItem);
}

resetDefinition = true;

currentDescription = [];
} else {

}
break;

case `END-DS`:
if (currentItem && currentItem.type === `struct`) {
scope.structs.push(currentItem);
resetDefinition = true;
if (dsScopes.length === 1) {
scope.structs.push(dsScopes.pop());
} else
if (dsScopes.length > 1) {
dsScopes[dsScopes.length - 2].subItems.push(dsScopes.pop());
}
break;

Expand Down Expand Up @@ -589,6 +596,13 @@ module.exports = class Parser {
}

} else {
if (!currentItem) {
if (dsScopes.length >= 1) {
// We do this as there can be many levels to data structures in free format
currentItem = dsScopes[dsScopes.length - 1];
}
}

if (currentItem && [`procedure`, `struct`].includes(currentItem.type)) {
if (currentItem.readParms) {
if (parts[0].startsWith(`DCL`))
Expand All @@ -611,6 +625,10 @@ module.exports = class Parser {

currentItem.subItems.push(currentSub);
currentSub = undefined;

if (currentItem.type === `struct`) {
resetDefinition = true;
}
}
}
}
Expand Down
40 changes: 40 additions & 0 deletions tests/suite/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1918,5 +1918,45 @@ module.exports = {
const scope = Obj_List.scope;
assert.strictEqual(scope.subroutines.length, 1);
assert.strictEqual(scope.variables.length, 1);
},

subds1: async () => {
const lines = [
`**FREE`,
``,
`Dcl-Ds DsChangingNodeRole Qualified;`,
` *n Int(10) Inz(0);`,
` *n VarChar(20) Inz('Primary Node');`,
` *n Int(10) Inz(1);`,
` *n VarChar(20) Inz('Backup node');`,
` *n Int(10) Inz(-1);`,
` *n VarChar(20) Inz('Replicate Node');`,
` *n Int(10) Inz(-2);`,
` *n VarChar(20) Inz('Changing Node');`,
` *n Int(10) Inz(-3);`,
` *n VarChar(20) Inz('*List');`,
` *n Int(10) Inz(-4);`,
` *n VarChar(20) Inz('Peer Node');`,
` Dcl-Ds Role Dim(1) Pos(1);`,
` Values Int(10);`,
` Descriotion VarChar(20);`,
` End-Ds Role;`,
`End-Ds DsChangingNodeRole;`,
``,
`Return;`,
``,
].join(`\n`);

const parser = new Parser();
const cache = await parser.getDocs(URI, lines);

assert.strictEqual(cache.structs.length, 1);

const DsChangingNodeRole = cache.find(`DsChangingNodeRole`);
assert.strictEqual(DsChangingNodeRole.name, `DsChangingNodeRole`);
assert.strictEqual(DsChangingNodeRole.position.line, 2);

assert.strictEqual(DsChangingNodeRole.subItems.length, 13);
assert.strictEqual(DsChangingNodeRole.subItems[12].name, `Role`);
}
}

0 comments on commit b5ea11a

Please sign in to comment.