private static final String IF = "if";
private static final String ELSE_IF = "else if";
private static final String ELSE = "else";
private static final String THEN = "then";
private class TwoTuple<T> {
public String token;
public T value;
private TwoTuple() {
}
private TwoTuple(String token, T t) {
this.token = token;
this.value = t;
}
}
private List<TwoTuple<Object>> tokens;
private TwoTuple<Object> result_token;
private Promise(List<TwoTuple<Object>> tokens) {
this.tokens = tokens;
}
// private Promise(List<TwoTuple<Object>> tokens, Throwable error) {
// this.tokens = tokens;
// this.error = error;
// }
private <R> Promise<R> programPromise(List<TwoTuple<Object>> tokens) {
if (tokens == null) {
throw new RuntimeException("please use begin() to start using promise in ef/eeseEf/else/thenDo !");
}
return new Promise<>(tokens);
}
public <R> Promise<R> begin() {
return programPromise(XType.list());
}
/**
* syntax :
* S -> if .then .T
* T -> else if .then .T | else |ε
* . 分隔詞組
*
* @param t
* @param <I>
* @return
*/
public <I> Promise<RESULT> ef(I t) {
tokens.add(new TwoTuple<>(IF, t));
// return programPromise(tokens);
return this;
}
public <I> Promise<RESULT> eeseEf(I t) {
tokens.add(new TwoTuple<>(ELSE_IF, t));
// return programPromise(tokens);
return this;
}
public <R> Promise<RESULT> thenDo(ReturnCallbackNoParam<R> callback) {
tokens.add(new TwoTuple<>(THEN, callback));
// return programPromise(tokens);
return this;
}
// public <R> Promise<RESULT> thenDo(ReturnCallbackWithParam<R, RESULT> callback) {
// tokens.add(new TwoTuple<>(THEN, callback));
//// return programPromise(tokens);
// return this;
// }
// public Promise<RESULT> thenDo(VoidCallbackWithParam<RESULT> callback) {
// tokens.add(new TwoTuple<>(THEN, callback));
//// return programPromise(tokens);
// return this;
// }
public Promise<RESULT> thenDo(VoidCallbackNoParam callback) {
tokens.add(new TwoTuple<>(THEN, callback));
// return programPromise(tokens);
return this;
}
public <R> Promise<RESULT> eese(ReturnCallbackNoParam<R> callback) {
tokens.add(new TwoTuple<>(ELSE, callback));
// return programPromise(tokens);
return this;
}
// public <R> Promise<RESULT> eese(ReturnCallbackWithParam<R, RESULT> callback) {
// tokens.add(new TwoTuple<>(ELSE, callback));
//// return programPromise(tokens);
// return this;
// }
// public Promise<RESULT> eese(VoidCallbackWithParam<RESULT> callback) {
// tokens.add(new TwoTuple<>(ELSE, callback));
//// return programPromise(tokens);
// return this;
// }
public Promise<RESULT> eese(VoidCallbackNoParam callback) {
tokens.add(new TwoTuple<>(ELSE, callback));
// return programPromise(tokens);
return this;
}
private <R> R whatCallback(TwoTuple<Object> token) {
R r = null;
if (token.value instanceof VoidCallbackNoParam) {
VoidCallbackNoParam callback = XType.cast(token.value);
callback.vcv();
}
// else if (token.value instanceof ReturnCallbackWithParam) {
// ReturnCallbackWithParam<R, RESULT> callback = XType.cast(token.value);
// r = callback.rci(XType.cast(value));
// }
else if (token.value instanceof ReturnCallbackNoParam) {
ReturnCallbackNoParam<R> callback = XType.cast(token.value);
r = callback.rcv();
}
// else if (token.value instanceof VoidCallbackWithParam) {
// VoidCallbackWithParam<RESULT> callback = XType.cast(token.value);
// callback.vci(XType.cast(value));
// }
return r;
}
//自頂向下分析
private void S_token(Iterator<TwoTuple<Object>> it) {
if(it.hasNext()) {
//S -> if then T
TwoTuple<Object> if_token = it.next();
if(IF.equals(if_token.token)) {
TwoTuple<Object> then_token = it.next();
if(THEN.equals(then_token.token)){
if(result_token == null && parseBoolean(if_token.value)) {
result_token = then_token;
// result_token_value_if_null(then_token);
}
//T -> else if then T | else | E
T_token(it);
}
}
}
}
private void T_token(Iterator<TwoTuple<Object>> it) {
if(it.hasNext()) {
TwoTuple<Object> t_token = it.next();
if(ELSE_IF.equals(t_token.token)) {
TwoTuple<Object> then_token = it.next();
if(THEN.equals(then_token.token)){
if(result_token == null && parseBoolean(t_token.value)) {
result_token = then_token;
}
//T -> else if then T | else | E
//recursion
T_token(it);
}
}else if(ELSE.equals(t_token.token)) {
if(result_token == null) {
result_token = t_token;
}
}
}
}
//不支持 if else 嵌套!
private <R> R analyzeTokensAndExec() {
//分析語法結構
//然後執行!
S_token(tokens.iterator());
return whatCallback(result_token);
// R r = null;
// if (tokens != null) {
// if (!tokens.isEmpty()) {
// TwoTuple<Object> tuple = tokens.get(0);
// //check first parameter,must start with if / match
// if (!IF.equals(tuple.token)) {
// throw new RuntimeException("please use structure begin().ef().thenDo().elseEf().thenDo().else().end()!");
// }
// for (int i = 0; tokens != null && i < tokens.size(); i++) {
// tuple = tokens.get(i);
// if (IF.equals(tuple.token) || ELSE_IF.equals(tuple.token)) {
// if (i + 1 >= tokens.size()) {
// throw new RuntimeException("not match if.elseif.else or if.else;after ef()/eeseEf() it's thenDo(),like ef().thenDo().elseEf().thenDo()");
// }
// TwoTuple<Object> nextToken = tokens.get(i + 1);
// if (THEN.equals(nextToken.token)) {
// if (parseBoolean(tuple.value)) {
// r = whatCallback(nextToken, tuple.value);
// break;//因爲是 if else 只執行一個!
// }
// }
// }
// }
// }
// }
// return r;
}
public <R> Promise<R> end() {
R r = analyzeTokensAndExec();
// clear tokens!
tokens = null;
return new Promise<>(r);
}
Promise.resolve().begin().ef(false).thenDo(()->{
XLog.lg("if");
}).eeseEf(false).thenDo(()->{
XLog.lg("else if");
}).eese(()->{
XLog.lg("else");
}).end();
else