diff --git a/src/kiss/Kiss.hx b/src/kiss/Kiss.hx index a99b6452..1a563efc 100644 --- a/src/kiss/Kiss.hx +++ b/src/kiss/Kiss.hx @@ -67,6 +67,19 @@ class Kiss { pos: Context.currentPos(), expr: ECall(readerExpToHaxeExpr(func, specialForms), [for (bodyExp in body) readerExpToHaxeExpr(bodyExp, specialForms)]) }; + case List(elements): + { + pos: Context.currentPos(), + expr: ENew({ + pack: ["kiss"], + name: "List" + }, [ + { + pos: Context.currentPos(), + expr: EArrayDecl([for (elementExp in elements) readerExpToHaxeExpr(elementExp, specialForms)]) + } + ]) + } case RawHaxe(code): Context.parse(code, Context.currentPos()); default: diff --git a/src/kiss/List.hx b/src/kiss/List.hx new file mode 100644 index 00000000..a90f1da4 --- /dev/null +++ b/src/kiss/List.hx @@ -0,0 +1,52 @@ +package kiss; + +@:forward(length, concat, contains, copy, filter, indexOf, // insert is re-implemented with negative index support + iterator, join, keyValueIterator, + lastIndexOf, map, pop, push, remove, resize, reverse, shift, // slice is re-implemented with negative index support + sort, + // splice is re-implemented with negative index support, + toString, unshift) +abstract List(Array) from Array to Array { + public inline function new(a:Array) { + this = a; + } + + @:from + static public function fromArray(a:Array) { + return new List(a); + } + + @:to + public function toArray() { + return this; + } + + inline function realIndex(idx:Int) { + return if (idx < 0) this.length + idx else idx; + } + + @:arrayAccess + public inline function get(idx:Int):Null { + return this[realIndex(idx)]; + } + + @:arrayAccess + public inline function arrayWrite(idx:Int, v:T):T { + this[realIndex(idx)] = v; + return v; + } + + function insert(idx:Int, v:T) { + this.insert(realIndex(idx), v); + } + + function slice(start:Int, ?end:Int) { + if (end == null) + end = this.length; + return this.slice(realIndex(start), realIndex(end)); + } + + function splice(start:Int, len:Int) { + return this.splice(realIndex(start), len); + } +} diff --git a/src/test/cases/BasicTestCase.hx b/src/test/cases/BasicTestCase.hx index a9cfc48f..9b289766 100644 --- a/src/test/cases/BasicTestCase.hx +++ b/src/test/cases/BasicTestCase.hx @@ -28,4 +28,17 @@ class BasicTestCase extends Test { function testMethod() { Assert.equals(5, new BasicTestCase().myMethod()); } + + function testArray() { + var arr = BasicTestCase.myArray; + Assert.equals(3, arr.length); + Assert.equals(1, arr[0]); + Assert.equals(2, arr[1]); + Assert.equals(3, arr[2]); + + // Kiss arrays can be negatively indexed like Python + Assert.equals(3, arr[-1]); + Assert.equals(2, arr[-2]); + Assert.equals(1, arr[-3]); + } } diff --git a/src/test/cases/BasicTestCase.kiss b/src/test/cases/BasicTestCase.kiss index 28f0cf08..ced91f52 100644 --- a/src/test/cases/BasicTestCase.kiss +++ b/src/test/cases/BasicTestCase.kiss @@ -16,4 +16,7 @@ (defprop myField 5) // (defmethod) declares instance methods -(defmethod myMethod [] this.myField) \ No newline at end of file +(defmethod myMethod [] this.myField) + +// [...] returns a Kiss array (they have special features and convert implicitly) +(defvar myArray [1 2 3]) \ No newline at end of file