2013-07-18 19 views
0

我試圖編譯一些個人語言erlang。我想創建一個模式匹配子句的函數。如何使用cerl定義通配符模式:c_clause

這是我的數據:

Data = 
    [ {a, <a_body> } 
    , {b, <b_body> } 
    , {c, <c_body> } 
    ]. 

這就是我想要的:

foo(a) -> <a_body>; 
foo(b) -> <b_body>; 
foo(c) -> <c_body>; 
foo(_) -> undefined. %% <- this 

我做的那一刻:

MkCaseClause = 
    fun({Pattern,Body}) -> 
     cerl:c_clause([cerl:c_atom(Pattern)], deep_literal(Body)) 
    end, 
WildCardClause = cerl:c_clause([ ??? ], cerl:c_atom(undefined)), 
CaseClauses = [MkCaseClause(S) || S <- Data] ++ [WildCardClause], 

所以,請幫我確定WildCardClause 。我看到,如果我打電話給我的編譯函數既不a也不b也不C它導致** exception error: no true branch found when evaluating an if expression in function ...

當我打印我的核心二郎代碼我得到這個:

當核心編譯
'myfuncname'/1 = 
    fun (Key) -> 
     case Key of 
      <'a'> when 'true' -> ... 
      <'b'> when 'true' -> ... 
      <'c'> when 'true' -> ... 
     end 

那麼好,case被翻譯成if。所以我需要在if表達式中指定一個true子句來獲得純粹的通配符。我不知道該怎麼做,因爲匹配trueif表達式和case是不同的語義。在一個案例中,true不是通配符。

如果我想要像{sometag,_,_,Thing} -> {ok, Thing}這樣的通配符匹配表達式會怎麼樣。

謝謝

回答

0

我已經找到一種方法來做到這一點

... 
WildCardVar = cerl:c_var('_Any'), 
WildCardClause = cerl:c_clause([WildCardVar], cerl:c_atom(undefined)), 
... 

應該對內部通配符工作太,但是你要小心,因爲到每個_通配符給不同的變量名稱只有多個_彼此不匹配,變量纔會這樣。

f(X,_, _) %% matches f(a,b,c) 
f(X,_X,_X) %% doesn't 
+0

接受我自己的答案,因爲經過進一步的研究,這就是erlang所做的。因爲這是唯一的答案:) – niahoo

相關問題