+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 }))
 | 
			
		||||
    >>> 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)
 | 
			
		||||
 | 
			
		||||
Lyng has built-in mutable array class `List` with simple literals:
 | 
			
		||||
 | 
			
		||||
@ -343,7 +343,7 @@ class Compiler(
 | 
			
		||||
                    context.addItem("it", false, itValue)
 | 
			
		||||
                } else {
 | 
			
		||||
                    // 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}")
 | 
			
		||||
                    for ((n, a) in argsDeclaration.args.withIndex()) {
 | 
			
		||||
                        if (n >= args.size) {
 | 
			
		||||
@ -351,10 +351,9 @@ class Compiler(
 | 
			
		||||
                                context.addItem(a.name, false, a.initialValue.execute(context))
 | 
			
		||||
                            else throw ScriptError(a.pos, "argument $n is out of scope")
 | 
			
		||||
                        } else {
 | 
			
		||||
                            val value = if( a.isEllipsis) {
 | 
			
		||||
                            val value = if (a.isEllipsis) {
 | 
			
		||||
                                ObjList(args.values.subList(n, args.values.size).toMutableList())
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            } else
 | 
			
		||||
                                args[n]
 | 
			
		||||
                            context.addItem(a.name, false, value)
 | 
			
		||||
                        }
 | 
			
		||||
@ -491,7 +490,10 @@ class Compiler(
 | 
			
		||||
        do {
 | 
			
		||||
            val t = cc.next()
 | 
			
		||||
            when (t.type) {
 | 
			
		||||
                Token.Type.RPAREN, Token.Type.COMMA -> {}
 | 
			
		||||
                Token.Type.NEWLINE,
 | 
			
		||||
                Token.Type.RPAREN, Token.Type.COMMA -> {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Token.Type.ELLIPSIS -> {
 | 
			
		||||
                    parseStatement(cc)?.let { args += ParsedArgument(it, t.pos, isSplat = true) }
 | 
			
		||||
                        ?: throw ScriptError(t.pos, "Expecting arguments list")
 | 
			
		||||
@ -501,9 +503,25 @@ class Compiler(
 | 
			
		||||
                    cc.previous()
 | 
			
		||||
                    parseExpression(cc)?.let { args += ParsedArgument(it, t.pos) }
 | 
			
		||||
                        ?: throw ScriptError(t.pos, "Expecting arguments list")
 | 
			
		||||
                    // Here should be a valid termination:
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } 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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -771,7 +789,7 @@ class Compiler(
 | 
			
		||||
                        throw lbe
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if( !wasBroken ) elseStatement?.let { s -> result = s.execute(it) }
 | 
			
		||||
            if (!wasBroken) elseStatement?.let { s -> result = s.execute(it) }
 | 
			
		||||
            result
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -958,7 +976,7 @@ class Compiler(
 | 
			
		||||
 | 
			
		||||
    private fun parseBlock(cc: CompilerContext, skipLeadingBrace: Boolean = false): Statement {
 | 
			
		||||
        val startPos = cc.currentPos()
 | 
			
		||||
        if( !skipLeadingBrace ) {
 | 
			
		||||
        if (!skipLeadingBrace) {
 | 
			
		||||
            val t = cc.next()
 | 
			
		||||
            if (t.type != Token.Type.LBRACE)
 | 
			
		||||
                throw ScriptError(t.pos, "Expected block body start: {")
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,13 @@ internal class CompilerContext(val tokens: List<Token>) {
 | 
			
		||||
        } 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 {
 | 
			
		||||
        val t = next()
 | 
			
		||||
        return if (t.type == typeId) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user