+lambda after fn call as last argument
This commit is contained in:
parent
29c643eed2
commit
c167ebe6a8
@ -325,6 +325,22 @@ one could be with ellipsis that means "the rest pf arguments as List":
|
|||||||
assert( [11, 21, 31] == mapValues( [1,2,3], { it*10+1 }))
|
assert( [11, 21, 31] == mapValues( [1,2,3], { it*10+1 }))
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
|
### Auto last parameter
|
||||||
|
|
||||||
|
When the function call is follower by the `{` in the same line, e.g. lambda immediately
|
||||||
|
after function call, it is treated as a last argument to the call, e.g.:
|
||||||
|
|
||||||
|
fun mapValues(iterable, transform) {
|
||||||
|
var result = []
|
||||||
|
for( x in iterable ) result += transform(x)
|
||||||
|
}
|
||||||
|
val mapped = mapValues( [1,2,3]) {
|
||||||
|
it*10+1
|
||||||
|
}
|
||||||
|
assert( [11, 21, 31] == mapped)
|
||||||
|
>>> void
|
||||||
|
|
||||||
|
|
||||||
# Lists (aka arrays)
|
# Lists (aka arrays)
|
||||||
|
|
||||||
Lyng has built-in mutable array class `List` with simple literals:
|
Lyng has built-in mutable array class `List` with simple literals:
|
||||||
|
@ -343,7 +343,7 @@ class Compiler(
|
|||||||
context.addItem("it", false, itValue)
|
context.addItem("it", false, itValue)
|
||||||
} else {
|
} else {
|
||||||
// assign vars as declared
|
// assign vars as declared
|
||||||
if( args.size != argsDeclaration.args.size && !argsDeclaration.args.last().isEllipsis)
|
if (args.size != argsDeclaration.args.size && !argsDeclaration.args.last().isEllipsis)
|
||||||
raiseArgumentError("Too many arguments : called with ${args.size}, lambda accepts only ${argsDeclaration.args.size}")
|
raiseArgumentError("Too many arguments : called with ${args.size}, lambda accepts only ${argsDeclaration.args.size}")
|
||||||
for ((n, a) in argsDeclaration.args.withIndex()) {
|
for ((n, a) in argsDeclaration.args.withIndex()) {
|
||||||
if (n >= args.size) {
|
if (n >= args.size) {
|
||||||
@ -351,10 +351,9 @@ class Compiler(
|
|||||||
context.addItem(a.name, false, a.initialValue.execute(context))
|
context.addItem(a.name, false, a.initialValue.execute(context))
|
||||||
else throw ScriptError(a.pos, "argument $n is out of scope")
|
else throw ScriptError(a.pos, "argument $n is out of scope")
|
||||||
} else {
|
} else {
|
||||||
val value = if( a.isEllipsis) {
|
val value = if (a.isEllipsis) {
|
||||||
ObjList(args.values.subList(n, args.values.size).toMutableList())
|
ObjList(args.values.subList(n, args.values.size).toMutableList())
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
args[n]
|
args[n]
|
||||||
context.addItem(a.name, false, value)
|
context.addItem(a.name, false, value)
|
||||||
}
|
}
|
||||||
@ -491,7 +490,10 @@ class Compiler(
|
|||||||
do {
|
do {
|
||||||
val t = cc.next()
|
val t = cc.next()
|
||||||
when (t.type) {
|
when (t.type) {
|
||||||
Token.Type.RPAREN, Token.Type.COMMA -> {}
|
Token.Type.NEWLINE,
|
||||||
|
Token.Type.RPAREN, Token.Type.COMMA -> {
|
||||||
|
}
|
||||||
|
|
||||||
Token.Type.ELLIPSIS -> {
|
Token.Type.ELLIPSIS -> {
|
||||||
parseStatement(cc)?.let { args += ParsedArgument(it, t.pos, isSplat = true) }
|
parseStatement(cc)?.let { args += ParsedArgument(it, t.pos, isSplat = true) }
|
||||||
?: throw ScriptError(t.pos, "Expecting arguments list")
|
?: throw ScriptError(t.pos, "Expecting arguments list")
|
||||||
@ -501,9 +503,25 @@ class Compiler(
|
|||||||
cc.previous()
|
cc.previous()
|
||||||
parseExpression(cc)?.let { args += ParsedArgument(it, t.pos) }
|
parseExpression(cc)?.let { args += ParsedArgument(it, t.pos) }
|
||||||
?: throw ScriptError(t.pos, "Expecting arguments list")
|
?: throw ScriptError(t.pos, "Expecting arguments list")
|
||||||
|
// Here should be a valid termination:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (t.type != Token.Type.RPAREN)
|
} while (t.type != Token.Type.RPAREN)
|
||||||
|
// block after?
|
||||||
|
val pos = cc.savePos()
|
||||||
|
val end = cc.next()
|
||||||
|
if (end.type == Token.Type.LBRACE) {
|
||||||
|
// last argument - callable
|
||||||
|
val callableAccessor = parseLambdaExpression(cc)
|
||||||
|
args += ParsedArgument(
|
||||||
|
// transform accessor to the callable:
|
||||||
|
statement {
|
||||||
|
callableAccessor.getter(this).value
|
||||||
|
},
|
||||||
|
end.pos
|
||||||
|
)
|
||||||
|
} else
|
||||||
|
cc.restorePos(pos)
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +789,7 @@ class Compiler(
|
|||||||
throw lbe
|
throw lbe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !wasBroken ) elseStatement?.let { s -> result = s.execute(it) }
|
if (!wasBroken) elseStatement?.let { s -> result = s.execute(it) }
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -958,7 +976,7 @@ class Compiler(
|
|||||||
|
|
||||||
private fun parseBlock(cc: CompilerContext, skipLeadingBrace: Boolean = false): Statement {
|
private fun parseBlock(cc: CompilerContext, skipLeadingBrace: Boolean = false): Statement {
|
||||||
val startPos = cc.currentPos()
|
val startPos = cc.currentPos()
|
||||||
if( !skipLeadingBrace ) {
|
if (!skipLeadingBrace) {
|
||||||
val t = cc.next()
|
val t = cc.next()
|
||||||
if (t.type != Token.Type.LBRACE)
|
if (t.type != Token.Type.LBRACE)
|
||||||
throw ScriptError(t.pos, "Expected block body start: {")
|
throw ScriptError(t.pos, "Expected block body start: {")
|
||||||
|
@ -55,6 +55,13 @@ internal class CompilerContext(val tokens: List<Token>) {
|
|||||||
} else true
|
} else true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
fun skipTokens(vararg tokenTypes: Token.Type) {
|
||||||
|
while( next().type in tokenTypes ) { /**/ }
|
||||||
|
previous()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun ifNextIs(typeId: Token.Type, f: (Token) -> Unit): Boolean {
|
fun ifNextIs(typeId: Token.Type, f: (Token) -> Unit): Boolean {
|
||||||
val t = next()
|
val t = next()
|
||||||
return if (t.type == typeId) {
|
return if (t.type == typeId) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user