ref #16 better processing of the last-block argument
+sample with national-characters vars
This commit is contained in:
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())
|
||||
// }
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user