fix: lambda now have correct closure
This commit is contained in:
		
							parent
							
								
									306a7f26ef
								
							
						
					
					
						commit
						c0cf190452
					
				
							
								
								
									
										15
									
								
								docs/OOP.md
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								docs/OOP.md
									
									
									
									
									
								
							@ -70,3 +70,18 @@ Regular methods are called on instances as usual `instance.method()`. The method
 | 
				
			|||||||
1. this instance methods;
 | 
					1. this instance methods;
 | 
				
			||||||
2. parents method: no guarantee but we enumerate parents in order of appearance;
 | 
					2. parents method: no guarantee but we enumerate parents in order of appearance;
 | 
				
			||||||
3. possible extension methods (scoped)
 | 
					3. possible extension methods (scoped)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Defining a new class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The class is a some data record with named fields and fixed order, in fact. To define a class,
 | 
				
			||||||
 | 
					just Provide a name and a record like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Vec2(x,y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This way, you have created a _constructor_, so calling `Vec2( 10, 20 )` would create an _instane_ of `Vec2` class:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Vec2(x,y)
 | 
				
			||||||
 | 
					    Vec2(10,20)
 | 
				
			||||||
 | 
					    >> eee
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TBD
 | 
				
			||||||
@ -47,7 +47,7 @@ One interesting way of using closure isolation is to keep state of the functions
 | 
				
			|||||||
    >>> 0
 | 
					    >>> 0
 | 
				
			||||||
    >>> 1
 | 
					    >>> 1
 | 
				
			||||||
    >>> 2
 | 
					    >>> 2
 | 
				
			||||||
    >>> void
 | 
					    >> void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Inner `counter` is not accessible from outside, no way; still it is kept 
 | 
					Inner `counter` is not accessible from outside, no way; still it is kept 
 | 
				
			||||||
between calls in the closure, as inner function `doit`, returned from the
 | 
					between calls in the closure, as inner function `doit`, returned from the
 | 
				
			||||||
@ -75,3 +75,15 @@ The example above could be rewritten using inner lambda, too:
 | 
				
			|||||||
    >>> 1
 | 
					    >>> 1
 | 
				
			||||||
    >>> 2
 | 
					    >>> 2
 | 
				
			||||||
    >>> void
 | 
					    >>> void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Lambda functions remember their scopes, so it will work the same as previous:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var counter = 200
 | 
				
			||||||
 | 
					    fun createLambda() {
 | 
				
			||||||
 | 
					        var counter = 0
 | 
				
			||||||
 | 
					        { counter += 1 }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    val c = createLambda()
 | 
				
			||||||
 | 
					    println(c)
 | 
				
			||||||
 | 
					    >> 1
 | 
				
			||||||
 | 
					    >> void
 | 
				
			||||||
							
								
								
									
										24
									
								
								docs/class_reference.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								docs/class_reference.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					# Classes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Declaring
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Foo1
 | 
				
			||||||
 | 
					    class Foo2() // same, empty constructor
 | 
				
			||||||
 | 
					    class Foo3() { // full
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    class Foo4 { // Only body
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					class_declaration = ["abstract",] "class" [, constructor] [, body]
 | 
				
			||||||
 | 
					constructor = "(", [field [, field]] ")
 | 
				
			||||||
 | 
					field = [visibility ,] [access ,] name [, typedecl]
 | 
				
			||||||
 | 
					body = [visibility] ("var", vardecl) | ("val", vardecl) | ("fun", fundecl)
 | 
				
			||||||
 | 
					visibility = "private" | "protected" | "internal"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Abstract classes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Contain one pr more abstract methods which must be implemented; though they
 | 
				
			||||||
 | 
					can have constructors, the instances of the abstract classes could not be
 | 
				
			||||||
 | 
					created independently
 | 
				
			||||||
@ -326,9 +326,11 @@ class Compiler(
 | 
				
			|||||||
            throw ScriptError(startPos, "lambda must have either valid arguments declaration with '->' or no arguments")
 | 
					            throw ScriptError(startPos, "lambda must have either valid arguments declaration with '->' or no arguments")
 | 
				
			||||||
        val pos = cc.currentPos()
 | 
					        val pos = cc.currentPos()
 | 
				
			||||||
        val body = parseBlock(cc, skipLeadingBrace = true)
 | 
					        val body = parseBlock(cc, skipLeadingBrace = true)
 | 
				
			||||||
        return Accessor { _ ->
 | 
					
 | 
				
			||||||
            statement {
 | 
					        var closure: Context? = null
 | 
				
			||||||
                val context = this.copy(pos)
 | 
					
 | 
				
			||||||
 | 
					        val callStatement = statement {
 | 
				
			||||||
 | 
					            val context = closure!!.copy(pos, args)
 | 
				
			||||||
            if (argsDeclaration == null) {
 | 
					            if (argsDeclaration == null) {
 | 
				
			||||||
                // no args: automatic var 'it'
 | 
					                // no args: automatic var 'it'
 | 
				
			||||||
                val l = args.values
 | 
					                val l = args.values
 | 
				
			||||||
@ -360,7 +362,11 @@ class Compiler(
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            body.execute(context)
 | 
					            body.execute(context)
 | 
				
			||||||
            }.asReadonly
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Accessor { x ->
 | 
				
			||||||
 | 
					            if( closure == null ) closure = x
 | 
				
			||||||
 | 
					            callStatement.asReadonly
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -402,12 +408,22 @@ class Compiler(
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum class AccessType {
 | 
				
			||||||
 | 
					        Val, Var, Default
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum class Visibility {
 | 
				
			||||||
 | 
					        Default, Public, Private, Protected, Internal
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data class ArgVar(
 | 
					    data class ArgVar(
 | 
				
			||||||
        val name: String,
 | 
					        val name: String,
 | 
				
			||||||
        val type: TypeDecl = TypeDecl.Obj,
 | 
					        val type: TypeDecl = TypeDecl.Obj,
 | 
				
			||||||
        val pos: Pos,
 | 
					        val pos: Pos,
 | 
				
			||||||
        val isEllipsis: Boolean,
 | 
					        val isEllipsis: Boolean,
 | 
				
			||||||
        val initialValue: Statement? = null
 | 
					        val initialValue: Statement? = null,
 | 
				
			||||||
 | 
					        val accessType: AccessType = AccessType.Default,
 | 
				
			||||||
 | 
					        val visibility: Visibility = Visibility.Default
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data class ArgsDeclaration(val args: List<ArgVar>, val endTokenType: Token.Type) {
 | 
					    data class ArgsDeclaration(val args: List<ArgVar>, val endTokenType: Token.Type) {
 | 
				
			||||||
@ -421,16 +437,73 @@ class Compiler(
 | 
				
			|||||||
     * Parse argument declaration, used in lambda (and later in fn too)
 | 
					     * Parse argument declaration, used in lambda (and later in fn too)
 | 
				
			||||||
     * @return declaration or null if there is no valid list of arguments
 | 
					     * @return declaration or null if there is no valid list of arguments
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private fun parseArgsDeclaration(cc: CompilerContext): ArgsDeclaration? {
 | 
					    private fun parseArgsDeclaration(cc: CompilerContext, isClassDeclaration: Boolean = false): ArgsDeclaration? {
 | 
				
			||||||
        val result = mutableListOf<ArgVar>()
 | 
					        val result = mutableListOf<ArgVar>()
 | 
				
			||||||
        var endTokenType: Token.Type? = null
 | 
					        var endTokenType: Token.Type? = null
 | 
				
			||||||
        val startPos = cc.savePos()
 | 
					        val startPos = cc.savePos()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (endTokenType == null) {
 | 
					        while (endTokenType == null) {
 | 
				
			||||||
            val t = cc.next()
 | 
					            var t = cc.next()
 | 
				
			||||||
            when (t.type) {
 | 
					            when (t.type) {
 | 
				
			||||||
                Token.Type.NEWLINE -> {}
 | 
					                Token.Type.NEWLINE -> {}
 | 
				
			||||||
                Token.Type.ID -> {
 | 
					                Token.Type.ID -> {
 | 
				
			||||||
 | 
					                    // visibility
 | 
				
			||||||
 | 
					                    val visibility = when (t.value) {
 | 
				
			||||||
 | 
					                        "private" -> {
 | 
				
			||||||
 | 
					                            if (!isClassDeclaration) {
 | 
				
			||||||
 | 
					                                cc.restorePos(startPos); return null
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            t = cc.next()
 | 
				
			||||||
 | 
					                            Visibility.Private
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        "protected" -> {
 | 
				
			||||||
 | 
					                            if (!isClassDeclaration) {
 | 
				
			||||||
 | 
					                                cc.restorePos(startPos); return null
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            t = cc.next()
 | 
				
			||||||
 | 
					                            Visibility.Protected
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        "internal" -> {
 | 
				
			||||||
 | 
					                            if (!isClassDeclaration) {
 | 
				
			||||||
 | 
					                                cc.restorePos(startPos); return null
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            t = cc.next()
 | 
				
			||||||
 | 
					                            Visibility.Internal
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        "public" -> {
 | 
				
			||||||
 | 
					                            if (!isClassDeclaration) {
 | 
				
			||||||
 | 
					                                cc.restorePos(startPos); return null
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            t = cc.next()
 | 
				
			||||||
 | 
					                            Visibility.Public
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        else -> Visibility.Default
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    // val/var?
 | 
				
			||||||
 | 
					                    val access = when (t.value) {
 | 
				
			||||||
 | 
					                        "val" -> {
 | 
				
			||||||
 | 
					                            if (!isClassDeclaration) {
 | 
				
			||||||
 | 
					                                cc.restorePos(startPos); return null
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            t = cc.next()
 | 
				
			||||||
 | 
					                            AccessType.Val
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        "var" -> {
 | 
				
			||||||
 | 
					                            if (!isClassDeclaration) {
 | 
				
			||||||
 | 
					                                cc.restorePos(startPos); return null
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            t = cc.next()
 | 
				
			||||||
 | 
					                            AccessType.Var
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        else -> AccessType.Default
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var defaultValue: Statement? = null
 | 
					                    var defaultValue: Statement? = null
 | 
				
			||||||
                    cc.ifNextIs(Token.Type.ASSIGN) {
 | 
					                    cc.ifNextIs(Token.Type.ASSIGN) {
 | 
				
			||||||
                        defaultValue = parseExpression(cc)
 | 
					                        defaultValue = parseExpression(cc)
 | 
				
			||||||
@ -438,7 +511,7 @@ class Compiler(
 | 
				
			|||||||
                    // type information
 | 
					                    // type information
 | 
				
			||||||
                    val typeInfo = parseTypeDeclaration(cc)
 | 
					                    val typeInfo = parseTypeDeclaration(cc)
 | 
				
			||||||
                    val isEllipsis = cc.skipTokenOfType(Token.Type.ELLIPSIS, isOptional = true)
 | 
					                    val isEllipsis = cc.skipTokenOfType(Token.Type.ELLIPSIS, isOptional = true)
 | 
				
			||||||
                    result += ArgVar(t.value, typeInfo, t.pos, isEllipsis, defaultValue)
 | 
					                    result += ArgVar(t.value, typeInfo, t.pos, isEllipsis, defaultValue, access, visibility)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // important: valid argument list continues with ',' and ends with '->' or ')'
 | 
					                    // important: valid argument list continues with ',' and ends with '->' or ')'
 | 
				
			||||||
                    // otherwise it is not an argument list:
 | 
					                    // otherwise it is not an argument list:
 | 
				
			||||||
@ -630,9 +703,36 @@ class Compiler(
 | 
				
			|||||||
        "continue" -> parseContinueStatement(id.pos, cc)
 | 
					        "continue" -> parseContinueStatement(id.pos, cc)
 | 
				
			||||||
        "fn", "fun" -> parseFunctionDeclaration(cc)
 | 
					        "fn", "fun" -> parseFunctionDeclaration(cc)
 | 
				
			||||||
        "if" -> parseIfStatement(cc)
 | 
					        "if" -> parseIfStatement(cc)
 | 
				
			||||||
 | 
					        "class" -> parseClassDeclaration(cc, false)
 | 
				
			||||||
 | 
					        "struct" -> parseClassDeclaration(cc, true)
 | 
				
			||||||
        else -> null
 | 
					        else -> null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private fun parseClassDeclaration(cc: CompilerContext, isStruct: Boolean): Statement {
 | 
				
			||||||
 | 
					        val nameToken = cc.requireToken(Token.Type.ID)
 | 
				
			||||||
 | 
					        val parsedArgs = parseArgsDeclaration(cc)
 | 
				
			||||||
 | 
					        cc.skipTokenOfType(Token.Type.NEWLINE, isOptional = true)
 | 
				
			||||||
 | 
					        val t = cc.next()
 | 
				
			||||||
 | 
					        if (t.type == Token.Type.LBRACE) {
 | 
				
			||||||
 | 
					            // parse body
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // create class
 | 
				
			||||||
 | 
					        val className = nameToken.value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        val constructorCode = statement {
 | 
				
			||||||
 | 
					//            val classContext = copy()
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        val newClass = ObjClass(className, parsedArgs?.args ?: emptyList())
 | 
				
			||||||
 | 
					//        statement {
 | 
				
			||||||
 | 
					//            addConst(nameToken.value, )
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					        TODO()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun getLabel(cc: CompilerContext, maxDepth: Int = 2): String? {
 | 
					    private fun getLabel(cc: CompilerContext, maxDepth: Int = 2): String? {
 | 
				
			||||||
        var cnt = 0
 | 
					        var cnt = 0
 | 
				
			||||||
        var found: String? = null
 | 
					        var found: String? = null
 | 
				
			||||||
@ -749,7 +849,7 @@ class Compiler(
 | 
				
			|||||||
        var result: Obj = ObjVoid
 | 
					        var result: Obj = ObjVoid
 | 
				
			||||||
        val iVar = ObjInt(0)
 | 
					        val iVar = ObjInt(0)
 | 
				
			||||||
        loopVar.value = iVar
 | 
					        loopVar.value = iVar
 | 
				
			||||||
        if( catchBreak) {
 | 
					        if (catchBreak) {
 | 
				
			||||||
            for (i in start..<end) {
 | 
					            for (i in start..<end) {
 | 
				
			||||||
                iVar.value = i.toLong()
 | 
					                iVar.value = i.toLong()
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
@ -1185,7 +1285,8 @@ class Compiler(
 | 
				
			|||||||
            Operator.simple(Token.Type.NOTIS, lastPrty) { c, a, b -> ObjBool(!a.isInstanceOf(b)) },
 | 
					            Operator.simple(Token.Type.NOTIS, lastPrty) { c, a, b -> ObjBool(!a.isInstanceOf(b)) },
 | 
				
			||||||
            // shuttle <=> 6
 | 
					            // shuttle <=> 6
 | 
				
			||||||
            Operator.simple(Token.Type.SHUTTLE, ++lastPrty) { c, a, b ->
 | 
					            Operator.simple(Token.Type.SHUTTLE, ++lastPrty) { c, a, b ->
 | 
				
			||||||
                ObjInt(a.compareTo(c, b).toLong()) },
 | 
					                ObjInt(a.compareTo(c, b).toLong())
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            // bit shifts 7
 | 
					            // bit shifts 7
 | 
				
			||||||
            Operator.simple(Token.Type.PLUS, ++lastPrty) { ctx, a, b -> a.plus(ctx, b) },
 | 
					            Operator.simple(Token.Type.PLUS, ++lastPrty) { ctx, a, b -> a.plus(ctx, b) },
 | 
				
			||||||
            Operator.simple(Token.Type.MINUS, lastPrty) { ctx, a, b -> a.minus(ctx, b) },
 | 
					            Operator.simple(Token.Type.MINUS, lastPrty) { ctx, a, b -> a.minus(ctx, b) },
 | 
				
			||||||
@ -1213,7 +1314,7 @@ class Compiler(
 | 
				
			|||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * The keywords that stop processing of expression term
 | 
					         * The keywords that stop processing of expression term
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        val stopKeywords = setOf("break", "continue", "return", "if", "when", "do", "while", "for")
 | 
					        val stopKeywords = setOf("break", "continue", "return", "if", "when", "do", "while", "for", "class", "struct")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,11 @@ import net.sergeych.synctools.ProtectedOp
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//typealias InstanceMethod = (Context, Obj) -> Obj
 | 
					//typealias InstanceMethod = (Context, Obj) -> Obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data class WithAccess<T>(var value: T, val isMutable: Boolean)
 | 
					data class WithAccess<T>(
 | 
				
			||||||
 | 
					    var value: T,
 | 
				
			||||||
 | 
					    val isMutable: Boolean,
 | 
				
			||||||
 | 
					    val visibility: Compiler.Visibility = Compiler.Visibility.Public
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data class Accessor(
 | 
					data class Accessor(
 | 
				
			||||||
    val getter: suspend (Context) -> WithAccess<Obj>,
 | 
					    val getter: suspend (Context) -> WithAccess<Obj>,
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,14 @@ val ObjClassType by lazy { ObjClass("Class") }
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class ObjClass(
 | 
					class ObjClass(
 | 
				
			||||||
    val className: String,
 | 
					    val className: String,
 | 
				
			||||||
 | 
					    val constructorArgs: List<Compiler.ArgVar> = emptyList(),
 | 
				
			||||||
    vararg val parents: ObjClass,
 | 
					    vararg val parents: ObjClass,
 | 
				
			||||||
) : Obj() {
 | 
					) : Obj() {
 | 
				
			||||||
 | 
					    constructor(
 | 
				
			||||||
 | 
					        className: String,
 | 
				
			||||||
 | 
					        vararg parents: ObjClass,
 | 
				
			||||||
 | 
					    ) : this(className, emptyList(), *parents)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val allParentsSet: Set<ObjClass> = parents.flatMap {
 | 
					    val allParentsSet: Set<ObjClass> = parents.flatMap {
 | 
				
			||||||
        listOf(it) + it.allParentsSet
 | 
					        listOf(it) + it.allParentsSet
 | 
				
			||||||
@ -22,7 +28,7 @@ class ObjClass(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//    private var initInstanceHandler: (suspend (Context, List<Obj>) -> Obj)? = null
 | 
					//    private var initInstanceHandler: (suspend (Context, List<Obj>) -> Obj)? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//    suspend fun newInstance(context: Context, vararg args: Obj): Obj =
 | 
					    //    suspend fun newInstance(context: Context, vararg args: Obj): Obj =
 | 
				
			||||||
//        initInstanceHandler?.invoke(context, args.toList())
 | 
					//        initInstanceHandler?.invoke(context, args.toList())
 | 
				
			||||||
//            ?: context.raiseError("No initInstance handler for $this")
 | 
					//            ?: context.raiseError("No initInstance handler for $this")
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@ -70,13 +76,14 @@ class ObjClass(
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Abstract class that must provide `iterator` method that returns [ObjIterator] instance.
 | 
					 * Abstract class that must provide `iterator` method that returns [ObjIterator] instance.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
val ObjIterable by lazy { ObjClass("Iterable").apply {
 | 
					val ObjIterable by lazy {
 | 
				
			||||||
 | 
					    ObjClass("Iterable").apply {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        addFn("toList") {
 | 
					        addFn("toList") {
 | 
				
			||||||
            val result = mutableListOf<Obj>()
 | 
					            val result = mutableListOf<Obj>()
 | 
				
			||||||
            val iterator = thisObj.invokeInstanceMethod(this, "iterator")
 | 
					            val iterator = thisObj.invokeInstanceMethod(this, "iterator")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while( iterator.invokeInstanceMethod(this, "hasNext").toBool() )
 | 
					            while (iterator.invokeInstanceMethod(this, "hasNext").toBool())
 | 
				
			||||||
                result += iterator.invokeInstanceMethod(this, "next")
 | 
					                result += iterator.invokeInstanceMethod(this, "next")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -87,7 +94,8 @@ val ObjIterable by lazy { ObjClass("Iterable").apply {
 | 
				
			|||||||
            ObjList(result)
 | 
					            ObjList(result)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Collection is an iterator with `size`]
 | 
					 * Collection is an iterator with `size`]
 | 
				
			||||||
@ -142,6 +150,10 @@ val ObjArray by lazy {
 | 
				
			|||||||
        addFn("iterator") {
 | 
					        addFn("iterator") {
 | 
				
			||||||
            ObjArrayIterator(thisObj).also { it.init(this) }
 | 
					            ObjArrayIterator(thisObj).also { it.init(this) }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        addFn("isample") { "ok".toObj()}
 | 
					        addFn("isample") { "ok".toObj() }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ObjInstance(override val objClass: ObjClass): Obj() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1167,6 +1167,7 @@ class ScriptTest {
 | 
				
			|||||||
        eval(
 | 
					        eval(
 | 
				
			||||||
            """
 | 
					            """
 | 
				
			||||||
            fun mapValues(iterable, transform) {
 | 
					            fun mapValues(iterable, transform) {
 | 
				
			||||||
 | 
					                println("start: ", transform)
 | 
				
			||||||
                var result = []
 | 
					                var result = []
 | 
				
			||||||
                for( x in iterable ) result += transform(x)
 | 
					                for( x in iterable ) result += transform(x)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1238,6 +1239,17 @@ class ScriptTest {
 | 
				
			|||||||
            assert( 5 <=> 7 < 0 )
 | 
					            assert( 5 <=> 7 < 0 )
 | 
				
			||||||
        """.trimIndent()
 | 
					        """.trimIndent()
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    fun simpleClassDelaration() = runTest {
 | 
				
			||||||
 | 
					        eval( """
 | 
				
			||||||
 | 
					//            class Vec2(x,y)
 | 
				
			||||||
 | 
					//             println(Vec2(1,2)::class)
 | 
				
			||||||
 | 
					            println("---------------------")
 | 
				
			||||||
 | 
					            println(Int::class)
 | 
				
			||||||
 | 
					        """.trimIndent()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -8,6 +8,7 @@ import net.sergeych.lyng.ObjVoid
 | 
				
			|||||||
import java.nio.file.Files
 | 
					import java.nio.file.Files
 | 
				
			||||||
import java.nio.file.Files.readAllLines
 | 
					import java.nio.file.Files.readAllLines
 | 
				
			||||||
import java.nio.file.Paths
 | 
					import java.nio.file.Paths
 | 
				
			||||||
 | 
					import kotlin.io.path.absolutePathString
 | 
				
			||||||
import kotlin.io.path.extension
 | 
					import kotlin.io.path.extension
 | 
				
			||||||
import kotlin.test.Test
 | 
					import kotlin.test.Test
 | 
				
			||||||
import kotlin.test.assertEquals
 | 
					import kotlin.test.assertEquals
 | 
				
			||||||
@ -41,7 +42,8 @@ data class DocTest(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun toString(): String {
 | 
					    override fun toString(): String {
 | 
				
			||||||
        return "DocTest:$fileName:${line + 1}..${line + sourceLines.size}"
 | 
					        val absPath = Paths.get(fileName).absolutePathString()
 | 
				
			||||||
 | 
					        return "DocTest: $absPath:${line + 1}"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val detailedString by lazy {
 | 
					    val detailedString by lazy {
 | 
				
			||||||
@ -190,7 +192,7 @@ suspend fun DocTest.test(context: Context = Context()) {
 | 
				
			|||||||
        if (error != null || expectedOutput != collectedOutput.toString() ||
 | 
					        if (error != null || expectedOutput != collectedOutput.toString() ||
 | 
				
			||||||
            expectedResult != result
 | 
					            expectedResult != result
 | 
				
			||||||
        ) {
 | 
					        ) {
 | 
				
			||||||
            println("Test failed: ${this.detailedString}")
 | 
					            System.err.println("\nfailed: ${this.detailedString}")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        error?.let {
 | 
					        error?.let {
 | 
				
			||||||
            fail("test failed", it)
 | 
					            fail("test failed", it)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user