Skip to content

Commit 975242d

Browse files
authored
Added LuaIterable extension and deprecated @luaIterator (#28)
* added LuaIterable extension and deprecated @luaIterator * a couple of minor edits Co-authored-by: Tom <tomblind@users.noreply.github.com>
1 parent c0de4bf commit 975242d

File tree

2 files changed

+153
-52
lines changed

2 files changed

+153
-52
lines changed

docs/advanced/compiler-annotations.md

Lines changed: 86 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -137,55 +137,6 @@ local inst = MyConstructor(3)
137137

138138
</SideBySide>
139139

140-
## @luaIterator
141-
142-
**Target elements:** `(declare) interface`
143-
144-
Denotes a type is a Lua iterator. When an object of a type with this annotation is used in a for...of statement, it will transpile directly as a lua iterator in a for...in statement, instead of being treated as a TypeScript iterable. Typically, this is used on an interface that extends `Iterable` or `Array` so that TypeScript will allow it to be used in a for...of statement.
145-
146-
**Example**
147-
148-
<SideBySide>
149-
150-
<!-- prettier-ignore -->
151-
```typescript
152-
/** @luaIterator */
153-
type LuaIterable<T> = Iterable<T>;
154-
155-
declare function myIterator(): LuaIterable<string>;
156-
for (const s of myIterator()) {}
157-
```
158-
159-
```lua
160-
for s in myIterator() do end
161-
```
162-
163-
</SideBySide>
164-
165-
This can also be combined with [@tupleReturn](#tuplereturn), if the iterator returns multiple values.
166-
167-
**Example**
168-
169-
<SideBySide>
170-
171-
<!-- prettier-ignore -->
172-
```typescript
173-
/** @luaIterator @tupleReturn */
174-
type LuaTupleIterable<T extends any[]> = Iterable<T>;
175-
176-
declare namespace string {
177-
function gmatch(s: string, pattern: string): LuaTupleIterable<string[]>;
178-
}
179-
180-
for (const [a, b] of string.gmatch("foo", "(.)(.)")) {}
181-
```
182-
183-
```lua
184-
for a, b in string.gmatch("foo", "(.)(.)") do end
185-
```
186-
187-
</SideBySide>
188-
189140
## @luaTable
190141

191142
**Target elements:** `type`
@@ -797,3 +748,89 @@ for i = 10, 1, -1 do end
797748
```
798749

799750
</SideBySide>
751+
752+
### @luaIterator
753+
754+
<DeprecatedInVersion deprecated="0.39.0" removed="TBD" />
755+
756+
**Target elements:** `(declare) interface`
757+
758+
Denotes a type is a Lua iterator. When an object of a type with this annotation is used in a for...of statement, it will transpile directly as a lua iterator in a for...in statement, instead of being treated as a TypeScript iterable. Typically, this is used on an interface that extends `Iterable` or `Array` so that TypeScript will allow it to be used in a for...of statement.
759+
760+
**Example**
761+
762+
<SideBySide>
763+
764+
<!-- prettier-ignore -->
765+
```typescript
766+
/** @luaIterator */
767+
type LuaIterator<T> = Iterable<T>;
768+
769+
declare function myIterator(): LuaIterator<string>;
770+
for (const s of myIterator()) {}
771+
```
772+
773+
```lua
774+
for s in myIterator() do end
775+
```
776+
777+
</SideBySide>
778+
779+
This can also be combined with [@tupleReturn](#tuplereturn), if the iterator returns multiple values.
780+
781+
**Example**
782+
783+
<SideBySide>
784+
785+
<!-- prettier-ignore -->
786+
```typescript
787+
/** @luaIterator @tupleReturn */
788+
type LuaTupleIterator<T extends any[]> = Iterable<T>;
789+
790+
declare namespace string {
791+
function gmatch(s: string, pattern: string): LuaTupleIterator<string[]>;
792+
}
793+
794+
for (const [a, b] of string.gmatch("foo", "(.)(.)")) {}
795+
```
796+
797+
```lua
798+
for a, b in string.gmatch("foo", "(.)(.)") do end
799+
```
800+
801+
</SideBySide>
802+
803+
**Upgrade Instructions**
804+
805+
Use the [`LuaIterable` and `LuaMultiReturn` language extensions](language-extensions.md#luaiterable-type) instead of a custom annotated types.
806+
807+
<SideBySide>
808+
809+
<!-- prettier-ignore -->
810+
```typescript
811+
declare function myIterator(): LuaIterable<string>;
812+
for (const s of myIterator()) {}
813+
```
814+
815+
```lua
816+
for s in myIterator() do end
817+
```
818+
819+
</SideBySide>
820+
821+
<SideBySide>
822+
823+
<!-- prettier-ignore -->
824+
```typescript
825+
declare namespace string {
826+
function gmatch(s: string, pattern: string): LuaIterable<LuaMultiReturn<string[]>>;
827+
}
828+
829+
for (const [a, b] of string.gmatch("foo", "(.)(.)")) {}
830+
```
831+
832+
```lua
833+
for a, b in string.gmatch("foo", "(.)(.)") do end
834+
```
835+
836+
</SideBySide>

docs/advanced/language-extensions.md

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ start, ____end = string.find("Hello, world!", "world")
4040
Prefer LuaMultiReturn over the similar [@tupleReturn annotation](./compiler-annotations.md#tuplereturn). LuaMultiReturn can do anything tupleReturn can, with the added benefit of being able to distinguish between actual tuple tables and multiple return values in the type system.
4141
:::
4242

43-
### \$multi
43+
### $multi
4444

4545
In order to create a function that returns multiple values it needs to return a `LuaMultiReturn<>` type. This is where the `$multi` function comes in. Calling `$multi` in a return statement will create an instance of the `LuaMultiReturn<>` type:
4646

@@ -84,6 +84,70 @@ for i = 5, 1, -1 do end
8484

8585
</SideBySide>
8686

87+
## LuaIterable Type
88+
89+
Iterators in Lua work quite differently than in Typescript/Javscript, so a special type is needed to use them.
90+
91+
For example, to declare and use a Lua function that returns an iterator for a set of strings, you can do this:
92+
93+
<SideBySide>
94+
95+
```ts
96+
declare function myIterator(): LuaIterable<string>;
97+
98+
for (const s of myIterator()) {
99+
console.log(s);
100+
}
101+
```
102+
103+
```lua
104+
for s in myIterator() do
105+
print(s)
106+
end
107+
```
108+
109+
</SideBySide>
110+
111+
Some iterators return multiple values each iteration. To declare these, combine `LuaIterable` with [`LuaMultiReturn`](#luamultireturn-type):
112+
113+
<SideBySide>
114+
115+
```ts
116+
declare function myIterator(): LuaIterable<LuaMultiReturn<[string, string]>>;
117+
118+
for (const [a, b] of myIterator()) {
119+
console.log(a, b);
120+
}
121+
```
122+
123+
```lua
124+
for a, b in myIterator() do
125+
print(a, b)
126+
end
127+
```
128+
129+
</SideBySide>
130+
131+
Lua iterators support passing an invisible state object each iteration. If your iterator type does this, you can declare the state type as a second type parameter:
132+
133+
```ts
134+
type MyStateType = ...
135+
declare function myIterator(): LuaIterable<string, MyStateType>;
136+
```
137+
138+
This is only really required if you need to use the iterator outside of a `for...of` loop.
139+
140+
```ts
141+
let [iteratorFunction, state, lastValue] = myIterator();
142+
while (true) {
143+
const value = iteratorFunction(state, lastValue);
144+
console.log(value);
145+
lastValue = value;
146+
}
147+
```
148+
149+
See the [Lua Reference Manual](https://www.lua.org/manual/5.3/manual.html#3.3.5) for more information on Lua for loops.
150+
87151
## Operator Map Types
88152

89153
Lua supports overloading operators on types using [metatable methods](https://www.lua.org/manual/5.4/manual.html#2.4) such as `__add`. But, Javascript and Typescript do not support this. In order to use overloaded operators on types that support them, you can declare special mapping functions in TS that will translate to those operators in Lua.
@@ -145,15 +209,15 @@ const scaled: Vector = Vector.mul(a, 2);
145209
- LuaAddition / LuaAdditionMethod (`a + b`)
146210
- LuaSubtraction / LuaSubtractionMethod (`a - b`)
147211
- LuaMultiplication / LuaMultiplicationMethod (`a * b`)
148-
- LuaDivision / LuaDivisionMethod (`a /b `)
212+
- LuaDivision / LuaDivisionMethod (`a / b `)
149213
- LuaModulo / LuaModuloMethod (`a % b`)
150214
- LuaPower / LuaPowerMethod (`a ^ b`)
151215
- LuaFloorDivision / LuaFloorDivisionMethod (`a // b`, only when targeting Lua 5.3 or later)
152216
- LuaNegation / LuaNegationMethod (`-x`)
153217
- Bitwise operators (only when targeting Lua 5.3 or later)
154218
- LuaBitwiseAnd / LuaBitwiseAndMethod (`a & b`)
155219
- LuaBitwiseOr / LuaBitwiseOrMethod (`a | b`)
156-
- LuaBitwiseExclusiveOr / LuaBitwiseExclusiveOrMethod (`a ^ b`)
220+
- LuaBitwiseExclusiveOr / LuaBitwiseExclusiveOrMethod (`a ~ b`)
157221
- LuaBitwiseLeftShift / LuaBitwiseLeftShiftMethod (`a << b`)
158222
- LuaBitwiseRightShift / LuaBitwiseRightShiftMethod (`a >> b`)
159223
- LuaBitwiseNot / LuaBitwiseNotMethod (`~x`)

0 commit comments

Comments
 (0)