ref #16 better processing of the last-block argument

+sample with national-characters vars
This commit is contained in:
sergeych committed 2025-06-11 10:54:06 +04:00
1 parent 194fc8aca6
commit 28b83f9892
5 files changed
+102 -8

No files matched your search

@@ -53,7 +53,11 @@ data class ArgsDeclaration(val params: List<Item>, val endTokenType: Token.Type)
val value = when {
i < callArgs.size -> callArgs[i]
a.defaultValue != null -> a.defaultValue.execute(context)
else -> context.raiseArgumentError("too few arguments for the call")
else -> {
println("callArgs: ${callArgs.joinToString()}")
println("tailBlockMode: ${arguments.tailBlockMode}")
context.raiseArgumentError("too few arguments for the call")
}
}
assign(a, value)
i++
@@ -140,7 +140,7 @@ class Compiler(
Token.Type.LPAREN -> {
cc.next()
// instance method call
val args = parseArgs(cc)
val args = parseArgs(cc).first
isCall = true
operand = Accessor { context ->
context.pos = next.pos
@@ -552,7 +552,11 @@ class Compiler(
return result
}
private fun parseArgs(cc: CompilerContext): List<ParsedArgument> {
/**
* Parse arguments list during the call and detect last block argument
* _following the parenthesis_ call: `(1,2) { ... }`
*/
private fun parseArgs(cc: CompilerContext): Pair<List<ParsedArgument>, Boolean> {
val args = mutableListOf<ParsedArgument>()
do {
@@ -578,6 +582,7 @@ class Compiler(
// block after?
val pos = cc.savePos()
val end = cc.next()
var lastBlockArgument = false
if (end.type == Token.Type.LBRACE) {
// last argument - callable
val callableAccessor = parseLambdaExpression(cc)
@@ -588,14 +593,16 @@ class Compiler(
},
end.pos
)
lastBlockArgument = true
} else
cc.restorePos(pos)
return args
return args to lastBlockArgument
}
private fun parseFunctionCall(cc: CompilerContext, left: Accessor, blockArgument: Boolean): Accessor {
// insofar, functions always return lvalue
var detectedBlockArgument = blockArgument
val args = if (blockArgument) {
val blockArg = ParsedArgument(
parseExpression(cc)
@@ -603,7 +610,9 @@ class Compiler(
)
listOf(blockArg)
} else {
parseArgs(cc)
val r = parseArgs(cc)
detectedBlockArgument = r.second
r.first
}
return Accessor { context ->
@@ -611,7 +620,7 @@ class Compiler(
v.value.callOn(
context.copy(
context.pos,
args.toArguments(context, blockArgument)
args.toArguments(context, detectedBlockArgument)
// Arguments(
// args.map { Arguments.Info((it.value as Statement).execute(context), it.pos) }
// ),
@@ -1640,4 +1640,49 @@ class ScriptTest {
""".trimIndent())
}
@Test
fun nationalCharsTest() = runTest {
eval("""
fun сумма_ряда(x, погрешность=0.0001, f) {
var сумма = 0
for( n in 1..100000) {
val следующая_сумма = сумма + f(x, n)
if( n > 1 && abs(следующая_сумма - сумма) < погрешность )
break следующая_сумма
сумма = следующая_сумма
}
else null
}
val x = сумма_ряда(1) { x, n ->
val sign = if( n % 2 == 1 ) 1 else -1
sign * pow(x, n) / n
}
assert( x - ln(2) < 0.001 )
""".trimIndent())
}
//
// @Test
// fun customIteratorTest() = runTest {
// eval("""
// fun сумма_ряда2(погрешность=0.0001, iterator) {
// var сумма = 0
// for( n in 1..100000) {
// if( !iterator.hasNext() ) break сумма
// val следующая_сумма = сумма + iterator.next()
// if( n > 1 && abs(следующая_сумма - сумма) < погрешность )
// break следующая_сумма
// сумма = следующая_сумма
// }
// else null
// }
// val
// val x = сумма_ряда2(1) { x, n ->
// val sign = if( n % 2 == 1 ) 1 else -1
// sign * pow(x, n) / n
// }
// assert( x - ln(2) < 0.001 )
// """.trimIndent())
// }
}