Skip to content

Instantly share code, notes, and snippets.

@Aidan63
Last active April 11, 2024 20:31
Show Gist options
  • Save Aidan63/d4ebb6dcf46e96c3f63fa419f3f26c9e to your computer and use it in GitHub Desktop.
Save Aidan63/d4ebb6dcf46e96c3f63fa419f3f26c9e to your computer and use it in GitHub Desktop.
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