Skip to content

Instantly share code, notes, and snippets.

@Aidan63
Created April 11, 2024 20:04
Show Gist options
  • Save Aidan63/6eebf0c4f2649c4c55c85e560a592a23 to your computer and use it in GitHub Desktop.
Save Aidan63/6eebf0c4f2649c4c55c85e560a592a23 to your computer and use it in GitHub Desktop.
import sys.thread.Thread;
import haxe.Exception;
enum CoroutineResult {
Suspended;
Success(v:Dynamic);
Error(exn:Dynamic);
}
function suspend(cont:(c:Dynamic->Dynamic->Void)->Void, _hx_continuation:Dynamic->Dynamic->Void):CoroutineResult {
Thread.current().events.run(() -> {
cont(_hx_continuation);
});
return Suspended;
}
class CoroDirectory {
public function new() {}
public function read(_hx_continuation:(_hx_result:Dynamic, _hx_error:Dynamic)->Void) {
var _hx_state = 1;
function _hx_stateMachine(_hx_result:Dynamic, _hx_error:Dynamic):CoroutineResult {
if (_hx_error != null) {
_hx_state = 3;
}
while (true) {
try {
switch _hx_state {
case 1: {
_hx_state = 2;
switch suspend(cont -> cont(["foo.txt", "bar.txt"], null), _hx_stateMachine) {
case CoroutineResult.Suspended:
return CoroutineResult.Suspended;
case CoroutineResult.Success(v):
_hx_result = v;
case CoroutineResult.Error(exn):
throw exn;
}
}
case 2: {
_hx_state = -1;
_hx_continuation(_hx_result, null);
return Success(_hx_result);
}
case 3: {
_hx_state = -1;
throw _hx_error;
}
default: {
throw new Exception("Invalid coroutine state");
}
};
} catch (_g:Exception) {
_hx_state = 3;
_hx_continuation(null, _g);
return Error(_g);
}
}
}
return _hx_stateMachine;
}
public static function open(_hx_continuation:(CoroDirectory, Dynamic)->Void) {
var _hx_state = 1;
function _hx_stateMachine(_hx_result:Dynamic, _hx_error:Dynamic):CoroutineResult {
if (_hx_error != null) {
_hx_state = 3;
}
while (true) {
try {
switch _hx_state {
case 1: {
_hx_state = 2;
switch suspend(cont -> cont(new CoroDirectory(), null), _hx_stateMachine) {
case Suspended:
return Suspended;
case Success(v):
_hx_result = v;
case Error(exn):
throw exn;
}
}
case 2: {
_hx_state = -1;
_hx_continuation(_hx_result, null);
return Success(_hx_result);
}
case 3: {
_hx_state = -1;
throw _hx_error;
}
default: {
throw new Exception("Invalid coroutine state");
}
}
} catch (_g:Exception) {
_hx_state = 3;
_hx_continuation(null, _g);
return Error(_g);
}
}
}
return _hx_stateMachine;
}
public static function read_dir(_hx_continuation:Dynamic->Dynamic->Void) {
var dir = (null:CoroDirectory);
var files = (null:Array<String>);
var _hx_state = 1;
function _hx_stateMachine(_hx_result:Dynamic, _hx_error:Dynamic) : CoroutineResult {
if (_hx_error != null) {
_hx_state = 4;
}
while (true) {
try {
switch _hx_state {
case 1: {
_hx_state = 2;
switch CoroDirectory.open(_hx_stateMachine)(null, null) {
case Suspended:
return Suspended;
case Success(v):
_hx_result = v;
case Error(exn):
throw exn;
}
}
case 2: {
_hx_state = 3;
dir = _hx_result;
switch dir.read(_hx_stateMachine)(null, null) {
case Suspended:
return Suspended;
case Success(v):
_hx_result = v;
case Error(exn):
throw exn;
}
}
case 3: {
_hx_state = -1;
files = _hx_result;
trace(files);
_hx_continuation(null, null);
return Success(_hx_result);
}
case 4: {
_hx_state = -1;
throw _hx_error;
}
default: {
throw new Exception("Invalid coroutine state");
}
}
} catch (_g:Exception) {
_hx_state = 4;
_hx_continuation(null, _g);
return Error(_g);
}
}
}
return _hx_stateMachine;
}
}
class Manual {
public static function main() {
var _hx_result = null;
var _hx_error = null;
var exited = false;
switch CoroDirectory.read_dir((result, error) -> {
switch error {
case null:
_hx_result = result;
case exn:
_hx_error = exn;
}
exited = true;
})(null, null) {
case Suspended:
while (exited == false) {
Thread.current().events.progress();
}
if (_hx_error != null) {
throw _hx_error;
} else {
trace(_hx_result);
}
case Success(v):
trace(v);
case Error(exn):
throw exn;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment