Skip to content

Instantly share code, notes, and snippets.

@Aidan63
Last active March 14, 2024 23:03
Show Gist options
  • Save Aidan63/3ff8baf8cdad659a3bd1750cd751825e to your computer and use it in GitHub Desktop.
Save Aidan63/3ff8baf8cdad659a3bd1750cd751825e to your computer and use it in GitHub Desktop.
import haxe.macro.Printer;
import haxe.macro.ExprTools;
import haxe.macro.Expr;
import haxe.macro.Context;
using Lambda;
typedef Ctx = { block : Array<Expr>, loops : Array<Array<Expr>> }
function find_autoclose_evar(els:Array<Expr>) : { index : Int, vars : Array<Var> } {
for (idx => el in els) {
switch el.expr {
case EMeta({ name : ":autoclose" }, { expr : EVars(vars) }):
return { index : idx, vars : vars };
case _:
continue;
}
}
return null;
}
function block_scope(ctx:Ctx, pos:Position, els:Array<Expr>):Expr {
return switch find_autoclose_evar(els) {
case null:
{ pos : pos, expr : EBlock(els.map(map.bind(ctx))) }
case found:
final before = els.slice(0, found.index).map(map.bind(ctx));
final close = macro @:mergeBlock $b{ found.vars.map(v -> macro if ($i{ v.name } != null) $i{ v.name }.close()) }
ctx.block.push(close);
if (ctx.loops.length > 0) {
ctx.loops[ctx.loops.length - 1].push(close);
}
final after = block_scope(ctx, pos, els.slice(found.index + 1));
ctx.block.pop();
macro {
@:mergeBlock $b{ before };
$e{ els[found.index] }
try $e{ after } catch (exn) {
$e{ close }
throw exn;
}
$e{ close }
}
}
}
function loop_scope(ctx:Ctx, e:Expr) {
//
}
function map(ctx:Ctx, e:Expr) {
return switch e.expr {
case EBlock(exprs):
block_scope(ctx, e.pos, exprs);
case EFor(it, expr):
ctx.loops.push([]);
final mapped = { pos : e.pos, expr : EFor(map(ctx, it), map(ctx, expr)) }
ctx.loops.pop();
mapped;
case EWhile(econd, e, normalWhile):
ctx.loops.push([]);
final mapped = { pos : e.pos, expr : EWhile(map(ctx, econd), map(ctx, e), normalWhile) }
ctx.loops.pop();
mapped;
case EBreak if (ctx.loops.length > 0):
final closes = ctx.loops[ctx.loops.length - 1].copy();
closes.reverse();
macro {
@:mergeBlock $b{ closes }
break;
}
case EContinue if (ctx.loops.length > 0):
final closes = ctx.loops[ctx.loops.length - 1].copy();
closes.reverse();
macro {
@:mergeBlock $b{ closes }
continue;
}
case EReturn(null):
final closes = ctx.block.copy();
closes.reverse();
macro {
@:mergeBlock $b{ closes }
return;
}
case EReturn(e):
final closes = ctx.block.copy();
closes.reverse();
macro {
final _hx_tmp = $e{ e };
@:mergeBlock $b{ closes }
return _hx_tmp;
}
case o:
ExprTools.map(e, map.bind(ctx));
}
return e;
}
macro function build():Array<Field> {
final fields = [];
for (field in Context.getBuildFields()) {
switch field.kind {
case FFun(f):
f.expr = map({ block : [], loops : [] }, f.expr);
case _:
//
}
fields.push(field);
}
return fields;
}
@:build(AutoClose.build())
class Main {
static function foo() {
var reader = sys.io.File.read("D:\\programming\\haxe\\disposable\\Main.hx", false);
try {
var writer = sys.io.File.write("test.txt", false);
try {
while ((! reader.eof())) {
var r2 = sys.io.File.read("D:\\programming\\haxe\\disposable\\Main.hx", false);
try {
var reader2 = sys.io.File.read("D:\\programming\\haxe\\disposable\\Main.hx", false);
try {
{
var _g = 0;
while ((_g < 5)) {
var i = _g ++;
haxe.Log.trace(i, {fileName : "Main.hx", lineNumber : 43, className : "Main", methodName : "foo"});
if ((i > 2)) continue;
};
};
writer.writeString(reader.readLine() + "\n");
{
if ((reader2 != null)) reader2.close();
if ((r2 != null)) r2.close();
continue;
};
} catch (exn:haxe.Exception) {
if ((reader2 != null)) reader2.close();
throw exn;
};
if ((reader2 != null)) reader2.close();
} catch (exn:haxe.Exception) {
if ((r2 != null)) r2.close();
throw exn;
};
if ((r2 != null)) r2.close();
};
{
var _hx_tmp = "yes";
if ((writer != null)) writer.close();
if ((reader != null)) reader.close();
return _hx_tmp;
};
} catch (exn:haxe.Exception) {
if ((writer != null)) writer.close();
throw exn;
};
if ((writer != null)) writer.close();
} catch (exn:haxe.Exception) {
if ((reader != null)) reader.close();
throw exn;
};
if ((reader != null)) reader.close();
}
@:keep
static function main() {
haxe.Log.trace(Main.foo(), {fileName : "Main.hx", lineNumber : 59, className : "Main", methodName : "main"});
}
}
@:build(AutoClose.build())
class Main {
static function foo() {
@:autoclose final reader = File.read("D:\\programming\\haxe\\disposable\\Main.hx", false);
@:autoclose final writer = File.write("test.txt", false);
while (!reader.eof()) {
@:autoclose final r2 = sys.io.File.read("D:\\programming\\haxe\\disposable\\Main.hx", false);
@:autoclose final reader2 = File.read("D:\\programming\\haxe\\disposable\\Main.hx", false);
for (i in 0...5) {
trace(i);
if (i > 2) {
continue;
}
}
writer.writeString(reader.readLine() + "\n");
continue;
}
return "yes";
}
static function main() {
trace(foo());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment