import morfa.base; // introduce 4 new operators to handle the if2 syntax operator then { kind = infix, precedence = mul, associativity = right} operator else1 { kind = infix, precedence = not, associativity = left } operator else2 { kind = infix, precedence = not, associativity = left } operator none { kind = infix, precedence = not, associativity = left } // function which bounds the condition expression to the if2 "actions" public func then(condition: IF2.Condition, actionHolder: IF2): void { actionHolder.actions[condition](); } // functions (bound to operators) used to "build" the if2 "statement" public func else1(bothAction: func(): void, else1Action: func(): void): IF2 { return IF2([IF2.Condition.both -> bothAction, IF2.Condition.else1 -> else1Action]); } public func else2(actionHolder: IF2, action: func(): void): IF2 { return checkAndAdd(actionHolder, action, IF2.Condition.else2); } public func none(actionHolder: IF2, action: func(): void): IF2 { return checkAndAdd(actionHolder, action, IF2.Condition.none); } // finally, function which combines two conditions into a "trigger" for the if2 "statement" public func if2(condition1: bool, condition2: bool): IF2.Condition { if (condition1 and condition2) return IF2.Condition.both; else if (condition1) return IF2.Condition.else1; else if (condition2) return IF2.Condition.else2; else return IF2.Condition.none; } // private helper function to build the IF2 structure func checkAndAdd(actionHolder: IF2, action: func(): void, actionName: IF2.Condition): IF2 { if (actionHolder.actions.contains(actionName)) throw new Exception("action defined twice for one condition in if2"); else actionHolder.actions[actionName] = action; return actionHolder; } // helper structure to process the if2 "statement" struct IF2 { public enum Condition { both, else1, else2, none }; public var actions: Dict; } // usage if2 (true, false) then func() { println("both true"); } else1 func() { println("first true"); } else2 func() { println("second true"); } none func() { println("none true"); };