Last active
October 3, 2017 14:47
-
-
Save skial/de6df6afe924b47d3a3e to your computer and use it in GitHub Desktop.
Code exercise while my internet was down for the safe navigation operator from AS3 started by this Haxe mailing list thread https://groups.google.com/forum/#!topic/haxelang/Rrj9AUbXGuA using Haxe 3.2.0 (git build development @ 3a255a8).
This file contains hidden or 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
-main Main | |
-js test.js | |
--next | |
## You need nodejs installed for this to work. | |
-cmd node test.js |
This file contains hidden or 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 ; | |
import haxe.macro.*; | |
import haxe.macro.Expr.ComplexType; | |
using haxe.macro.ExprTools; | |
/** | |
* ... | |
* @author Skial Bainn | |
*/ | |
class Builder { | |
public static var localVars:Array<Expr> = []; | |
public static function build() { | |
var cls = Context.getLocalClass().get(); | |
var fields = Context.getBuildFields(); | |
for (field in fields) switch (field.kind) { | |
case FFun(m) if (m.expr != null): | |
m.expr.iter( process ); | |
case _: | |
} | |
return fields; | |
} | |
public static function process(expr:Expr) { | |
switch (expr) { | |
case macro var $id:$type: | |
localVars.push( expr ); | |
case macro var $id:$type = $e: | |
localVars.push( expr ); | |
case { expr:EBinop(OpBoolOr, e1, e2), pos:p } : | |
for (ee in [e1, e2]) inspect( ee, findLastType( expr ) ); | |
case _: | |
expr.iter( process ); | |
} | |
} | |
public static function inspect(expr:Expr, ctype:ComplexType) { | |
switch (expr) { | |
case { expr:EBinop(OpBoolOr, _, _), pos:_ }: | |
expr.iter( inspect.bind(_, ctype) ); | |
case { expr:EConst(CIdent(ident)), pos:p } : | |
for (i in 0...localVars.length) switch (localVars[i]) { | |
case { expr:EVars([v = { name:n, type:t, expr:e } ]), pos:_ } : | |
if (n == ident) { | |
if (t == null) { | |
t = ctype; | |
} | |
if (!Context.unify(ComplexTypeTools.toType(t), Context.getType('Bool'))) { | |
v.type = macro :Main.N<$t>; | |
} | |
} | |
case _: | |
} | |
case _: | |
} | |
} | |
public static function findLastType(expr:Expr) { | |
var result = null; | |
switch (expr) { | |
case { expr:EConst(c), pos:_ } : | |
result = switch(c) { | |
case CInt(_): macro:Int; | |
case CFloat(_): macro:Float; | |
case CString(_): macro:String; | |
case CRegexp(_, _): macro:EReg; | |
case CIdent(i): | |
null; | |
} | |
case _: | |
expr.iter( function(e) result = findLastType(e) ); | |
} | |
return result; | |
} | |
} |
This file contains hidden or 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 ; | |
/** | |
* ... | |
* @author Skial Bainn | |
*/ | |
@:build( Builder.build() ) | |
class Main { | |
public static function main() new Main(); | |
public function new() { | |
var a = null; | |
var b = null; | |
trace( a || b || 'woot' ); | |
} | |
} | |
abstract N<T>(T) from T to T { | |
public inline function new(v:T) this = v; | |
@:to public inline function toBool():Bool return this != null; | |
@:op(A || B) | |
public static inline function or<T>(a:N<T>, b:N<T>) { | |
return (a:N<T>) ? a : b; | |
} | |
} |
This file contains hidden or 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
(function () { "use strict"; | |
var console = (1,eval)('this').console || {log:function(){}}; | |
var Main = function() { | |
var a = null; | |
var b = null; | |
console.log((function($this) { | |
var $r; | |
var a1; | |
if(a != null) a1 = a; else a1 = b; | |
$r = a1 != null?a1:"woot"; | |
return $r; | |
}(this))); | |
}; | |
Main.main = function() { | |
new Main(); | |
}; | |
var _Main = {}; | |
_Main.N_Impl_ = {}; | |
_Main.N_Impl_._new = function(v) { | |
return v; | |
}; | |
_Main.N_Impl_.toBool = function(this1) { | |
return this1 != null; | |
}; | |
_Main.N_Impl_.or = function(a,b) { | |
if(a != null) return a; else return b; | |
}; | |
Main.main(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment