diff options
author | nea <nea@nea.moe> | 2023-08-09 20:06:15 +0200 |
---|---|---|
committer | nea <nea@nea.moe> | 2023-08-09 20:06:15 +0200 |
commit | 0b518030fcdffb68e6b62ffddfe4b784db9f272c (patch) | |
tree | a4dbed21824703010e7f2d28008b1d8bdbb1cfe9 /src/LispData.kt | |
parent | fc3911c68a4a8a0ff916b858e5fe029ed2ebe493 (diff) | |
download | nealisp-0b518030fcdffb68e6b62ffddfe4b784db9f272c.tar.gz nealisp-0b518030fcdffb68e6b62ffddfe4b784db9f272c.tar.bz2 nealisp-0b518030fcdffb68e6b62ffddfe4b784db9f272c.zip |
Add rest arguments
Diffstat (limited to 'src/LispData.kt')
-rw-r--r-- | src/LispData.kt | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/LispData.kt b/src/LispData.kt index 11a2451..1745762 100644 --- a/src/LispData.kt +++ b/src/LispData.kt @@ -7,6 +7,7 @@ sealed class LispData { data class LispString(val string: String) : LispData() data class LispNumber(val value: Double) : LispData() data class LispNode(val node: LispAst.LispNode) : LispData() + class LispList(val elements: List<LispData>) : LispData() sealed class LispExecutable() : LispData() { abstract fun execute( executionContext: LispExecutionContext, @@ -30,17 +31,26 @@ sealed class LispData { stackFrame: StackFrame, args: List<LispAst.LispNode> ): LispData { - if (argNames.size != args.size) { + + val invocationFrame = declarationStackFrame.fork() + if (argNames.lastOrNull() == "...") { + for ((name, value) in argNames.dropLast(1).zip(args)) { + invocationFrame.setValueLocal(name, executionContext.resolveValue(stackFrame, value)) + } + invocationFrame.setValueLocal( + "...", + LispList( + args.drop(argNames.size - 1).map { executionContext.resolveValue(stackFrame, it) }) + ) + } else if (argNames.size != args.size) { return executionContext.reportError( "Expected ${argNames.size} arguments, got ${args.size} instead", callsite ) - } - val invocationFrame = declarationStackFrame.fork() - - for ((name, value) in argNames.zip(args)) { - invocationFrame.setValueLocal(name, executionContext.resolveValue(stackFrame, value)) - } + } else + for ((name, value) in argNames.zip(args)) { + invocationFrame.setValueLocal(name, executionContext.resolveValue(stackFrame, value)) + } return executionContext.executeLisp(invocationFrame, body) } } |