Skip to content

Instantly share code, notes, and snippets.

@markknol
Forked from jdonaldson/Main.hx
Created December 28, 2019 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markknol/540cf3ebbd68a6e235b95c3ba906a0e6 to your computer and use it in GitHub Desktop.
Save markknol/540cf3ebbd68a6e235b95c3ba906a0e6 to your computer and use it in GitHub Desktop.
Paths example
class Main {
static function main(){
var router = Paths.buildRouter(Page);
var o = router(["Home"]);
trace(o + " is the value for o");
var p = router(["Foo","Baz", "1"]);
trace(p + " is the value for p");
var q = router(["Scales","Guitar","Chromatic"]);
trace(q + " is the value for q");
}
}
enum abstract Bar(String) from String to String {
var Baz ='heeey';
var Bing='hii';
var Boo = 'hooo';
}
enum Page {
Home;
Foo(bar : Bar, val : Int);
Scales(instrument:GuitarMember, scale:Scale);
Intervals(instrument:GuitarMember, scale:Scale, key:Note);
ChordProgressionPage(instrument:GuitarMember, scale:Scale, key:Note, highlighted:Scale);
SuspendedChordsPage(instrument:GuitarMember, scale:Scale, key:Note, highlighted:Scale);
PowerChordsPage(instrument:GuitarMember, scale:Scale, key:Note, highlighted:Scale);
ScaleNotesPage(instrument:GuitarMember, scale:Scale, key:Note);
ChordNotesPage(instrument:GuitarMember, scale:Scale, key:Note);
NoteOverviewPage(instrument:GuitarMember, key:Note);
}
@:enum abstract GuitarMember(String) from String to String {
var Guitar = "guitar";
var Ukulele = "ukulele";
var BassGuitar = "bass-guitar";
var Banjo = "banjo";
var Mandolin = "mandolin";
}
@:enum abstract Scale(String) from String to String {
var Chromatic = "chromatic";
var NaturalMinor = "natural-minor";
var NaturalMajor = "natural-major";
var MinorPentatonic = "minor-pentatonic";
var MajorPentatonic = "major-pentatonic";
var MelodicMinor = "melodic-minor";
var HarmonicMinor = "harmonic-minor";
var Blues = "blues";
var Ionian = "ionian";
var Dorian = "dorian";
var Phygian = "phygian";
var Lydian = "lydian";
var Mixolydian = "mixolydian";
var Aeolian = "aeolian";
var Locrian = "locrian";
}
@:enum abstract Note(String) from String to String {
/* 1 */ var C = "e";
/* 2 */ var CSharp = "c-sharp";
/* 3 */ var D = "d";
/* 4 */ var DSharp = "d-sharp";
/* 5 */ var E = "e";
/* 6 */ var F = "f";
/* 7 */ var FSharp = "f-sharp";
/* 8 */ var G = "g";
/* 9 */ var GSharp = "g-sharp";
/* 10 */ var A = "a";
/* 11 */ var ASharp = "a-sharp";
/* 12 */ var B = "b";
}
Main.hx|7 info| Home is the value for o
Main.hx|10 info| Foo(heeey,1) is the value for p
Main.hx|13 info| Scales(guitar,chromatic) is the value for q
#if macro
import haxe.macro.Expr;
import haxe.macro.Type;
import haxe.macro.Context;
import haxe.macro.Context.currentPos as pos;
import haxe.macro.Context.followWithAbstracts as follow;
#end
class Paths {
macro public static function buildRouter(enm : Expr) : Expr {
return macro function(paths : Array<String>) {
return ${buildSwitchExpr(enm)}
};
}
#if macro
public static function buildExprFromType(type : Type, idx = 0) : Expr {
return switch type {
case TEnum(_,_) : buildSwitchFromType(type);
case TAbstract(abs, []) if (abs.get().module == "StdTypes") : {
switch (abs.get().name) {
case "String" : macro paths.shift();
case "Int" : macro Std.parseInt(paths.shift());
case "Float" : macro Std.parseFloat(paths.shift());
default : macro null;
}
}
case TAbstract(abs, []) : {
var impl = abs.get().impl.get();
buildSwitchFromAbsImpl(impl);
}
default : macro null;
}
}
public static function buildCaseFromEnumField(enmf: EnumField) : Case {
return switch enmf.type {
case TEnum(enm, []) : {
return {
values : [macro $v{enmf.name}],
expr : macro $i{enmf.name}
}
}
case TFun(args, ret) : {
var arg_exprs = Lambda.map(args, a->{
return buildExprFromType(a.t);
});
return {
values : [macro $v{enmf.name}],
expr : macro $i{enmf.name}($a{arg_exprs})
}
}
default : null;
};
}
public static function buildSwitchFromAbsImpl(impl : ClassType ) : Expr {
var cases = Lambda.map(impl.statics.get(), s->{
return {
values : [macro $v{s.name}],
expr : macro $i{s.name},
guard : null
};
});
cases.push({
values : [macro _],
expr : macro null,
guard : null
});
return {
expr : ESwitch(macro paths.shift(), cases, null),
pos : Context.currentPos()
};
}
public static function buildSwitchFromType(type : Type, idx = 0) : Expr {
return switch type {
case TEnum(enm, []) : {
var enme = enm.get();
var cases : Array<Case> = Lambda.map(enme.constructs, c-> {
return buildCaseFromEnumField(enme.constructs.get(c.name));
});
cases.push({
values : [macro _],
expr : macro null
});
return {
expr : ESwitch( macro paths.shift(), cases, null),
pos : Context.currentPos()
}
}
default : macro null;
}
}
public static function buildSwitchExpr(expr : Expr , idx = 0) : Expr {
return switch expr.expr{
case EConst(CIdent(val)) : buildSwitchFromType(Context.getType(val));
case _: throw new Error("not an enum", Context.currentPos());
}
}
#end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment