Last active
April 11, 2024 20:31
-
-
Save Aidan63/d4ebb6dcf46e96c3f63fa419f3f26c9e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package t2; | |
import sys.thread.Thread; | |
import haxe.Exception; | |
interface IContinuation<T> { | |
function resumeWith(_hx_result:T, _hx_error:Exception):Void; | |
} | |
enum CoroutineResult<T> { | |
Suspended; | |
Success(v:T); | |
Error(exn:Exception); | |
} | |
function suspend(cont:IContinuation<Any>->Void, completion:IContinuation<Any>):CoroutineResult<Any> { | |
Thread.current().events.run(() -> { | |
cont(completion); | |
}); | |
return Suspended; | |
} | |
private class HxCoro_open implements IContinuation<Any> { | |
public final completion:IContinuation<Any>; | |
public var _hx_state:Int; | |
public var _hx_error:Exception; | |
public var _hx_result:Any; | |
public function new(completion) { | |
this.completion = completion; | |
_hx_state = 1; | |
} | |
public function resumeWith(_hx_result:Any, _hx_error:Exception) { | |
this._hx_result = _hx_result; | |
this._hx_error = _hx_error; | |
ClassCoroDirectory.open(this); | |
} | |
} | |
private class HxCoro_read implements IContinuation<Any> { | |
final self:ClassCoroDirectory; | |
public final completion:IContinuation<Any>; | |
public var _hx_state:Int; | |
public var _hx_error:Exception; | |
public var _hx_result:Any; | |
public function new(self, completion) { | |
this.self = self; | |
this.completion = completion; | |
_hx_state = 1; | |
} | |
public function resumeWith(_hx_result:Any, _hx_error:Exception) { | |
this._hx_result = _hx_result; | |
this._hx_error = _hx_error; | |
self.read(this); | |
} | |
} | |
private class HxCoro_read_dir implements IContinuation<Any> { | |
public final completion:IContinuation<Any>; | |
public var _hx_state:Int; | |
public var _hx_error:Exception; | |
public var _hx_result:Any; | |
public var dir:ClassCoroDirectory; | |
public var files:Array<String>; | |
public function new(completion) { | |
this.completion = completion; | |
_hx_state = 1; | |
} | |
public function resumeWith(_hx_result:Any, _hx_error:Exception) { | |
this._hx_result = _hx_result; | |
this._hx_error = _hx_error; | |
ClassCoroDirectory.read_dir(this); | |
} | |
} | |
class ClassCoroDirectory { | |
public function new() {} | |
public static function read_dir(completion:IContinuation<Any>):CoroutineResult<Dynamic> { | |
final continuation = if (completion is HxCoro_read_dir) (cast completion : HxCoro_read_dir) else new HxCoro_read_dir(completion); | |
while (true) { | |
try { | |
switch continuation._hx_state { | |
case 1: | |
{ | |
continuation._hx_state = 2; | |
switch ClassCoroDirectory.open(continuation) { | |
case Suspended: | |
return Suspended; | |
case Success(v): | |
continuation._hx_result = v; | |
case Error(exn): | |
throw exn; | |
} | |
} | |
case 2: | |
{ | |
continuation._hx_state = 3; | |
continuation.dir = cast continuation._hx_result; | |
switch continuation.dir.read(continuation) { | |
case Suspended: | |
return Suspended; | |
case Success(v): | |
continuation._hx_result = v; | |
case Error(exn): | |
throw exn; | |
} | |
}; | |
case 3: | |
{ | |
continuation._hx_state = -1; | |
continuation.files = cast continuation._hx_result; | |
trace(continuation.files); | |
continuation.completion.resumeWith(null, null); | |
return Success(continuation._hx_result); | |
} | |
case 4: | |
{ | |
continuation._hx_state = -1; | |
throw continuation._hx_error; | |
} | |
default: | |
{ | |
throw "Invalid coroutine state"; | |
} | |
}; | |
} catch (_g:Exception) { | |
continuation._hx_state = 4; | |
continuation.completion.resumeWith(null, _g); | |
return Error(_g); | |
} | |
} | |
} | |
public static function open(completion:IContinuation<Any>):CoroutineResult<ClassCoroDirectory> { | |
final continuation = if (completion is HxCoro_open) (cast completion : HxCoro_open) else new HxCoro_open(completion); | |
while (true) { | |
try { | |
switch continuation._hx_state { | |
case 1: | |
{ | |
continuation._hx_state = 2; | |
switch suspend(cont -> cont.resumeWith(new ClassCoroDirectory(), null), continuation) { | |
case Suspended: | |
return Suspended; | |
case Success(v): | |
continuation._hx_result = v; | |
case Error(exn): | |
throw exn; | |
} | |
} | |
case 2: | |
{ | |
continuation._hx_state = -1; | |
continuation.completion.resumeWith(continuation._hx_result, continuation._hx_error); | |
return Success(continuation._hx_result); | |
} | |
case 3: | |
{ | |
continuation._hx_state = -1; | |
throw continuation._hx_error; | |
} | |
default: | |
{ | |
throw new Exception("Invalid coroutine state"); | |
} | |
} | |
} catch (_g:Exception) { | |
continuation._hx_state = 3; | |
continuation.completion.resumeWith(null, _g); | |
return Error(_g); | |
} | |
} | |
} | |
public function read(completion:IContinuation<Any>):CoroutineResult<Array<String>> { | |
final continuation = if (completion is HxCoro_read) (cast completion : HxCoro_read) else new HxCoro_read(this, completion); | |
while (true) { | |
try { | |
switch continuation._hx_state { | |
case 1: | |
{ | |
continuation._hx_state = 2; | |
switch suspend(cont -> cont.resumeWith(["foo.txt", "bar.txt"], null), continuation) { | |
case Suspended: | |
return Suspended; | |
case Success(v): | |
continuation._hx_result = v; | |
case Error(exn): | |
throw exn; | |
} | |
} | |
case 2: | |
{ | |
continuation._hx_state = -1; | |
continuation.completion.resumeWith(continuation._hx_result, continuation._hx_error); | |
return Success(continuation._hx_result); | |
} | |
case 3: | |
{ | |
continuation._hx_state = -1; | |
throw continuation._hx_error; | |
} | |
default: | |
{ | |
throw new Exception("Invalid coroutine state"); | |
} | |
} | |
} catch (_g:Exception) { | |
continuation._hx_state = 3; | |
continuation.completion.resumeWith(null, _g); | |
return Error(_g); | |
} | |
} | |
} | |
} | |
class HxCoro_read_dir_start implements IContinuation<Any> { | |
final _hx_result:Array<Dynamic>; | |
final _hx_error:Array<Exception>; | |
public var completed:Bool; | |
public function new(_hx_result, _hx_error) { | |
this._hx_result = _hx_result; | |
this._hx_error = _hx_error; | |
completed = false; | |
} | |
public function resumeWith(_hx_result:Any, _hx_error:Exception) { | |
this._hx_result[0] = _hx_result; | |
this._hx_error[0] = _hx_error; | |
completed = true; | |
} | |
} | |
class ClassBased { | |
public static function main() { | |
final _hx_result = [null]; | |
final _hx_error = [null]; | |
final continuation = new HxCoro_read_dir_start(_hx_result, _hx_error); | |
switch ClassCoroDirectory.read_dir(continuation) { | |
case Suspended: | |
while (!continuation.completed) { | |
Thread.current().events.progress(); | |
} | |
case Success(v): | |
_hx_result[0] = v; | |
case Error(exn): | |
_hx_error[0] = exn; | |
} | |
trace(_hx_result[0], _hx_error[0]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment