Skip to content

Commit

Permalink
feat-fix: nested data frame reassignments
Browse files Browse the repository at this point in the history
  • Loading branch information
EagleoutIce committed Sep 9, 2024
1 parent 953465d commit b4ee94c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ export interface AssignmentConfiguration extends ForceArguments {
readonly canBeReplacement?: boolean
}

function findRootAccess<OtherInfo>(node: RNode<OtherInfo & ParentInformation>): RSymbol<OtherInfo & ParentInformation> | undefined {
let current = node
while(current.type === RType.Access) {
current = current.accessed
}
if(current.type === RType.Symbol) {
return current
} else {
return undefined
}
}

/**
* Processes an assignment, i.e., `<target> <- <source>`.
* Handling it as a function call \`&lt;-\` `(<target>, <source>)`.
Expand Down Expand Up @@ -95,6 +107,29 @@ export function processAssignment<OtherInfo>(
dataflowLogger.debug(`Assignment ${name.content} has an access as target => replacement function ${target.lexeme}`)
const replacement = toReplacementSymbol(target, target.operator, config.superAssignment ?? false)
return processAsNamedCall(replacement, data, replacement.content, [toUnnamedArgument(target.accessed, data.completeAst.idMap), ...target.access, source])
} else if(type === RType.Access) {
const rootArg = findRootAccess(target)
if(rootArg) {
const res = processKnownFunctionCall({
name,
args: [rootArg, source],
rootId,
data,
reverseOrder: !config.swapSourceAndTarget,
forceArgs: config.forceArgs
})

return processAssignmentToSymbol<OtherInfo & ParentInformation>({
...config,
nameOfAssignmentFunction: name.content,
source,
target: rootArg,
args: getEffectiveOrder(config, res.processedArguments as [DataflowInformation, DataflowInformation]),
rootId,
data,
information: res.information,
})
}
} else if(type === RType.String) {
return processAssignmentToString(target, args, name, rootId, data, config, source)
}
Expand All @@ -114,7 +149,7 @@ function extractSourceAndTarget<OtherInfo>(args: readonly RFunctionArgument<Othe
}

function produceWrittenNodes<OtherInfo>(rootId: NodeId, target: DataflowInformation, isFunctionDef: boolean, data: DataflowProcessorInformation<OtherInfo>, makeMaybe: boolean): IdentifierDefinition[] {
return target.in.map(ref => ({
return [...target.in, ...target.unknownReferences].map(ref => ({
...ref,
kind: isFunctionDef ? 'function' : 'variable',
definedAt: rootId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,13 @@ print(res)`
assertSliced(label('Loop Re-Iterate', ['name-normal', ...OperatorDatabase['<-'].capabilities, 'numbers', 'normal-definition', 'newlines', 'unnamed-arguments', 'call-normal', 'infix-calls', 'double-bracket-access', 'binary-operator', 'return', 'implicit-return']),
shell, code, ['7@print'], code)
})
describe('Nested dataframe assignments', () => {
const code = `df <- foo()
df$a[x > 3] <- 5
print(df)`
assertSliced(label('Simple reassignment', ['name-normal', ...OperatorDatabase['<-'].capabilities, 'numbers', 'normal-definition', 'newlines', 'unnamed-arguments', 'call-normal', 'infix-calls', 'double-bracket-access', 'binary-operator', 'return', 'implicit-return']),
shell, code, ['3@print'], code)
})
})
describe('Closures', () => {
assertSliced(label('closure w/ default arguments',['name-normal', ...OperatorDatabase['<-'].capabilities, 'formals-default', 'numbers', 'newlines', 'implicit-return', 'normal-definition', 'closures', 'unnamed-arguments']),
Expand Down

0 comments on commit b4ee94c

Please sign in to comment.