Skip to content

Commit

Permalink
chore: use more early return
Browse files Browse the repository at this point in the history
  • Loading branch information
theseanl committed Jan 22, 2024
1 parent bd1f972 commit 37ae5c0
Showing 1 changed file with 52 additions and 53 deletions.
105 changes: 52 additions & 53 deletions packages/unified-latex-util-macros/libs/newcommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ export function createMacroExpander(

return (macro: Ast.Macro) => {
const retTree = structuredClone(cachedSubstitutionTree);
const args = macro.args;

const stack: number[] = [];
let lastSelfReference: number | null = null;
Expand All @@ -229,68 +228,68 @@ export function createMacroExpander(
}

const hashNum = node.number;
const arg = args?.[hashNum - 1];
const arg = macro.args?.[hashNum - 1];

// Check if this argument is -NoValue-
if (!arg || match.blankArgument(arg)) {
// Check if there exists a default argument for this hash number
const defaultArg = defaultArgs[hashNum - 1];
if (!defaultArg) {
return s(`#${hashNum}`);
}
// If `arg` is provided, return it
if (arg && !match.blankArgument(arg)) {
return arg.content;
}

// Detect self-references
if (stack.includes(hashNum)) {
lastSelfReference = hashNum;
return s(`#${hashNum}`);
}
// Check if there exists a default argument for this hash number
const defaultArg = defaultArgs[hashNum - 1];
if (!defaultArg) {
return s(`#${hashNum}`);
}

// `defaultArg` is a string expression. The same `defaultArg` may be parsed
// differently depending on the context of `macro`, so we cannot cache
// the parse result of `defaultArg`. Currently we just call `parse` without
// taking account of parsing contexts, so actually the result can be cached,
// but this is not the correct thing to do. FIXME: we should probably pass
// some options that is provided to whatever function that called this to
// the below parse call. Note that `parse` is done in several passes, and we
// may be able to cache result of a first few passes that aren't context-dependent.
const subst = parse(defaultArg).content;
const nextHashNums = getMacroSubstitutionHashNumbers(subst);
// Detect self-references
if (stack.includes(hashNum)) {
lastSelfReference = hashNum;
return s(`#${hashNum}`);
}

if (nextHashNums.size === 0) {
return subst;
}
// `defaultArg` is a string expression. The same `defaultArg` may be parsed
// differently depending on the context of `macro`, so we cannot cache
// the parse result of `defaultArg`. Currently we just call `parse` without
// taking account of parsing contexts, so actually the result can be cached,
// but this is not the correct thing to do. FIXME: we should probably pass
// some options that is provided to whatever function that called this to
// the below parse call. Note that `parse` is done in several passes, and we
// may be able to cache result of a first few passes that aren't context-dependent.
const subst = parse(defaultArg).content;
const nextHashNums = getMacroSubstitutionHashNumbers(subst);

stack.push(hashNum);
try {
expandArgs(subst);
if (nextHashNums.size === 0) {
return subst;
}

if (lastSelfReference !== hashNum) {
return subst;
}
stack.push(hashNum);
try {
expandArgs(subst);

// At this point, we have encountered #n while expanding #n.
// Check if we got exactly #n by expanding #n,
// in which case we should return the -NoValue-.
if (`#${hashNum}` === printRaw(subst)) {
// We are good, clear the last self-reference variable
lastSelfReference = null;
return emptyArg();
}
if (lastSelfReference !== hashNum) {
return subst;
}

console.warn(
`Detected unrecoverable self-reference while expanding macro: ${printRaw(
macro
)}`
);
// Return a placeholder string, so that we know that
// this code path is not taken in unit tests.
return s("-Circular-");
} finally {
stack.pop();
// At this point, we have encountered #n while expanding #n.
// Check if we got exactly #n by expanding #n,
// in which case we should return the -NoValue-.
if (`#${hashNum}` === printRaw(subst)) {
// We are good, clear the last self-reference variable
lastSelfReference = null;
return emptyArg();
}
}

return arg.content;
console.warn(
`Detected unrecoverable self-reference while expanding macro: ${printRaw(
macro
)}`
);
// Return a placeholder string, so that we know that
// this code path is not taken in unit tests.
return s("-Circular-");
} finally {
stack.pop();
}
});
}

Expand Down

0 comments on commit 37ae5c0

Please sign in to comment.