2015-01-24 1 views
2

나는 Haxe에서 컴파일 타임 어서션을하고 싶다. 뭔가를 할 것이 좋을 것이다 :Haxe 용 C++ static_assert 같은 것이 있습니까?

static inline var important_number = 42; 

public function f():Void { 
    static_assert(important_number > 64, "important number is too small for this implementation!"); 
} 

내 질문은 : 다른 Haxe 컴파일 타임 주장을 할 수있는 가장 좋은 방법은 무엇인가, Haxe 여기에 올바른 경로를 매크로로입니까?

아래에 내가 true/false를 전달하면이 매크로가 작동합니다 (아무 것도 반환하지 않거나 아무 것도 반환하지 않아야 함). 그러나 나는 "컴파일 타임에 결국 부울이되는 모든 것"의보다 일반적인 경우에이 작업을 수행하는 방법을 확신하지 못합니다.

class Assert { 
/* Static assert */ 
macro static public function s(e:Expr, errorString:String):Expr { 
    switch(e.expr) { 
     case EConst(c): 
      switch(c) { 
       case CIdent("true"): 
        return e; 
       case CIdent("false"): 
        throw new Error(errorString, e.pos); 
       default: 
        throw new Error("I only accept true/false right now", e.pos); 
      } 
     default: 
      throw new Error("I only accept true/false right now", e.pos); 
    } 
} 
} 

Assert.s(false, "yep, it's a compile time error"); 
Assert.s(true, "business as usual"); 
Assert.s(6 == 9, "i don't seem to work yet"); 

업데이트 1 :

같은 몇 가지 간단한 경우에 사용할 수 있습니다 # 오류있는이 :

#if ios 
    trace("it just works!"); 
#else 
    #error("you didn't implement this yet!"); 
#end 

솔루션 : 그래서 여기

내가 지금 사용하고 무엇을 아마 경고가 있지만 간단한 정적 어설 션을 위해 작동하는 것 같습니다 :

import haxe.macro.Context; 
import haxe.macro.Expr; 
import haxe.macro.ExprTools; 

class Assert { 
    /* Static assert */ 
    macro static public function s(expr:Expr, ?error:String):Expr { 
     if (error == null) { 
      error = ""; 
     } 

     if (expr == null) { 
      throw new Error("Expression must be non-null", expr.pos); 
     } 

     var value = ExprTools.getValue(Context.getTypedExpr(Context.typeExpr(expr))); 

     if (value == null) { 
      throw new Error("Expression value is null", expr.pos); 
     } 
     else if (value != true && value != false) { 
      throw new Error("Expression does not evaluate to a boolean value", expr.pos); 
     } 
     else if(value == false) { 
      throw new Error("Assertion failure: " + ExprTools.toString(expr) + " " + "[ " + error + " ]", expr.pos); 
     } 

     return macro { }; 
    } 
} 
+0

매크로가 정적 어설 션과 어떤 관련이 있습니까? 그것은 컴파일 타임이 아닌 런타임이 될 Error를 던집니다. – Gama11

+0

아니요, 컴파일 타임 오류입니다. – stroncium

+1

@ Gama11 매크로가 컴파일시에만 평가된다고 가정하면, 그 때 던지기도 반드시 발생해야합니다. –

답변

2

Expr을 평가하고 컴파일 타임에 값을 얻으려면 ExprTools.getValue을 사용할 수 있습니다. source을 보면 실제로 질문에 게시 된 것과 비슷한 기술을 사용하고 있습니다.

ExprTools.getValue(Context.getTypedExpr(Context.typeExpr(expr)))을 사용하면 모든 인라인 변수 또는 expr 내부의 매크로 함수가 해결됩니다.

노 작업을 반환하는 경우 간단히 return macro {};을 사용할 수 있습니다.

관련 문제