Skip to content

Instantly share code, notes, and snippets.

@nadako
Last active August 29, 2015 14:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nadako/278da78c33369a2827a8 to your computer and use it in GitHub Desktop.
Save nadako/278da78c33369a2827a8 to your computer and use it in GitHub Desktop.
CoffeeScript-like destructurize. This is now added to https://github.com/nadako/haxe-thingies repository.
using Unpack;
class Main {
static function main() {
f().unpackInto( [ v1, { a: { length: v2 } }, { a: [ v3, _, v4 ] } ] );
trace(v1); // { a: [ 1 ] }
trace(v2); // 2
trace(v3); // 4
trace(v4); // 5
var a = 1, b = 2;
[a, b].unpackInto(b, a);
trace(a); // 2
trace(b); // 1
}
static function f() {
return [{a: [1]}, {a: [2, 3]}, {a: [4, 10, 5]}];
}
}
import haxe.macro.Context;
import haxe.macro.Expr;
using haxe.macro.ExprTools;
@:dce
class Unpack {
public static macro function unpackInto(object:Expr, pattern:Expr, rest:Array<Expr>):Expr {
// allow easy syntax for array unpacking
if (rest.length > 0)
pattern = macro @:pos(pattern.pos) $a{[pattern].concat(rest)};
var vars = [];
var unpackExpr = unpackRec(object, pattern, vars);
var result = [for (name in vars) macro var $name];
result.push(unpackExpr);
return macro @:mergeBlock $b{result};
}
#if macro
static function unpackRec(object:Expr, pattern:Expr, vars:Array<String>):Expr {
var result = [];
function capture(valueExpr:Expr, captureExpr:Expr) {
switch (captureExpr) {
case macro $i{name}:
if (name == "_")
return;
vars.push(name);
result.push(macro $i{name} = $valueExpr);
default:
result.push(unpackRec(valueExpr, captureExpr, vars));
}
}
switch (pattern.expr) {
case EArrayDecl(values):
var i = 0;
for (v in values)
capture(macro tmp[$v{i++}], v);
case EObjectDecl(fields):
for (f in fields) {
var fieldName = f.field;
capture(macro tmp.$fieldName, f.expr);
}
default:
throw new Error("Unsupported unpack expression", pattern.pos);
}
if (result.length > 0)
result.unshift(macro var tmp = $object);
return macro $b{result};
}
#end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment