functions are rewritten to new standard argparser/emitter too
This commit is contained in:
		
							parent
							
								
									71a2933066
								
							
						
					
					
						commit
						9a08da0dfd
					
				@ -348,7 +348,7 @@ class Compiler(
 | 
			
		||||
                context.addItem("it", false, itValue)
 | 
			
		||||
            } else {
 | 
			
		||||
                // assign vars as declared the standard way
 | 
			
		||||
                argsDeclaration.assignToContext(context)
 | 
			
		||||
                argsDeclaration.assignToContext(context, defaultAccessType = AccessType.Val)
 | 
			
		||||
            }
 | 
			
		||||
            body.execute(context)
 | 
			
		||||
        }
 | 
			
		||||
@ -417,6 +417,11 @@ class Compiler(
 | 
			
		||||
        while (endTokenType == null) {
 | 
			
		||||
            var t = cc.next()
 | 
			
		||||
            when (t.type) {
 | 
			
		||||
                Token.Type.RPAREN, Token.Type.ARROW -> {
 | 
			
		||||
                    // empty list?
 | 
			
		||||
                    endTokenType = t.type
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Token.Type.NEWLINE -> {}
 | 
			
		||||
                Token.Type.ID -> {
 | 
			
		||||
                    // visibility
 | 
			
		||||
@ -1046,12 +1051,6 @@ class Compiler(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data class FnParamDef(
 | 
			
		||||
        val name: String,
 | 
			
		||||
        val pos: Pos,
 | 
			
		||||
        val defaultValue: Statement? = null
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private fun parseFunctionDeclaration(tokens: CompilerContext): Statement {
 | 
			
		||||
        var t = tokens.next()
 | 
			
		||||
        val start = t.pos
 | 
			
		||||
@ -1062,27 +1061,10 @@ class Compiler(
 | 
			
		||||
        t = tokens.next()
 | 
			
		||||
        if (t.type != Token.Type.LPAREN)
 | 
			
		||||
            throw ScriptError(t.pos, "Bad function definition: expected '(' after 'fn ${name}'")
 | 
			
		||||
        val params = mutableListOf<FnParamDef>()
 | 
			
		||||
        var defaultListStarted = false
 | 
			
		||||
        do {
 | 
			
		||||
            t = tokens.next()
 | 
			
		||||
            if (t.type == Token.Type.RPAREN)
 | 
			
		||||
                break
 | 
			
		||||
            if (t.type != Token.Type.ID)
 | 
			
		||||
                throw ScriptError(t.pos, "Expected identifier after '('")
 | 
			
		||||
            val n = tokens.next()
 | 
			
		||||
            val defaultValue = if (n.type == Token.Type.ASSIGN) {
 | 
			
		||||
                parseExpression(tokens)?.also { defaultListStarted = true }
 | 
			
		||||
                    ?: throw ScriptError(n.pos, "Expected initialization expression")
 | 
			
		||||
            } else {
 | 
			
		||||
                if (defaultListStarted)
 | 
			
		||||
                    throw ScriptError(n.pos, "requires default value too")
 | 
			
		||||
                if (n.type != Token.Type.COMMA)
 | 
			
		||||
                    tokens.previous()
 | 
			
		||||
                null
 | 
			
		||||
            }
 | 
			
		||||
            params.add(FnParamDef(t.value, t.pos, defaultValue))
 | 
			
		||||
        } while (true)
 | 
			
		||||
 | 
			
		||||
        val argsDeclaration = parseArgsDeclaration(tokens)
 | 
			
		||||
        if( argsDeclaration == null || argsDeclaration.endTokenType != Token.Type.RPAREN)
 | 
			
		||||
            throw ScriptError(t.pos, "Bad function definition: expected valid argument declaration or () after 'fn ${name}'")
 | 
			
		||||
 | 
			
		||||
        // Here we should be at open body
 | 
			
		||||
        val fnStatements = parseBlock(tokens)
 | 
			
		||||
@ -1096,21 +1078,7 @@ class Compiler(
 | 
			
		||||
            val context = closure?.copy() ?: callerContext.raiseError("bug: closure not set")
 | 
			
		||||
 | 
			
		||||
            // load params from caller context
 | 
			
		||||
            for ((i, d) in params.withIndex()) {
 | 
			
		||||
                if (i < callerContext.args.size)
 | 
			
		||||
                    context.addItem(d.name, false, callerContext.args.list[i].value)
 | 
			
		||||
                else
 | 
			
		||||
                    context.addItem(
 | 
			
		||||
                        d.name,
 | 
			
		||||
                        false,
 | 
			
		||||
                        d.defaultValue?.execute(context)
 | 
			
		||||
                            ?: throw ScriptError(
 | 
			
		||||
                                context.pos,
 | 
			
		||||
                                "missing required argument #${1 + i}: ${d.name}"
 | 
			
		||||
                            )
 | 
			
		||||
                    )
 | 
			
		||||
            }
 | 
			
		||||
            // save closure
 | 
			
		||||
            argsDeclaration.assignToContext(context, callerContext.args, defaultAccessType = AccessType.Val)
 | 
			
		||||
            fnStatements.execute(context)
 | 
			
		||||
        }
 | 
			
		||||
        return statement(start) { context ->
 | 
			
		||||
 | 
			
		||||
@ -528,7 +528,7 @@ class ScriptTest {
 | 
			
		||||
        // equal args,
 | 
			
		||||
        // less args, no ellipsis, defaults, ok
 | 
			
		||||
        val ttEnd = Token.Type.RBRACE
 | 
			
		||||
        var pa = ArgsDeclaration(listOf(
 | 
			
		||||
        val pa = ArgsDeclaration(listOf(
 | 
			
		||||
            ArgsDeclaration.Item("a"),
 | 
			
		||||
            ArgsDeclaration.Item("b", isEllipsis = true),
 | 
			
		||||
        ), ttEnd)
 | 
			
		||||
@ -551,7 +551,7 @@ class ScriptTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testAssignArgumentsStartEllipsis() = runTest {
 | 
			
		||||
        val ttEnd = Token.Type.RBRACE
 | 
			
		||||
        var pa = ArgsDeclaration(listOf(
 | 
			
		||||
        val pa = ArgsDeclaration(listOf(
 | 
			
		||||
            ArgsDeclaration.Item("a", isEllipsis = true),
 | 
			
		||||
            ArgsDeclaration.Item("b"),
 | 
			
		||||
            ArgsDeclaration.Item("c"),
 | 
			
		||||
@ -583,7 +583,7 @@ class ScriptTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testAssignArgumentsmiddleEllipsis() = runTest {
 | 
			
		||||
        val ttEnd = Token.Type.RBRACE
 | 
			
		||||
        var pa = ArgsDeclaration(listOf(
 | 
			
		||||
        val pa = ArgsDeclaration(listOf(
 | 
			
		||||
            ArgsDeclaration.Item("i"),
 | 
			
		||||
            ArgsDeclaration.Item("a", isEllipsis = true),
 | 
			
		||||
            ArgsDeclaration.Item("b"),
 | 
			
		||||
@ -1306,6 +1306,17 @@ class ScriptTest {
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testNewFnParser() = runTest {
 | 
			
		||||
        eval(
 | 
			
		||||
            """
 | 
			
		||||
                fun f1(a,b) { a + b }
 | 
			
		||||
                println(f1(1,2))
 | 
			
		||||
                assertEquals( 7, f1(3,4) )
 | 
			
		||||
        """.trimIndent()
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testSpoilArgsBug() = runTest {
 | 
			
		||||
        eval(
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user