A small menubar app that allows you to switch between R versions quickly (if you have multiple versions of R framework installed). https://rud.is/rswitch
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.5 KiB

5 years ago
//
// CombiningEvaluator.swift
// SwiftSoup
//
// Created by Nabil Chatbi on 23/10/16.
// Copyright © 2016 Nabil Chatbi.. All rights reserved.
//
import Foundation
/**
* Base combining (and, or) evaluator.
*/
public class CombiningEvaluator: Evaluator {
public private(set) var evaluators: Array<Evaluator>
var num: Int = 0
public override init() {
evaluators = Array<Evaluator>()
super.init()
}
public init(_ evaluators: Array<Evaluator>) {
self.evaluators = evaluators
super.init()
updateNumEvaluators()
}
public init(_ evaluators: Evaluator...) {
self.evaluators = evaluators
super.init()
updateNumEvaluators()
}
func rightMostEvaluator() -> Evaluator? {
return num > 0 && evaluators.count > 0 ? evaluators[num - 1] : nil
}
func replaceRightMostEvaluator(_ replacement: Evaluator) {
evaluators[num - 1] = replacement
}
func updateNumEvaluators() {
// used so we don't need to bash on size() for every match test
num = evaluators.count
}
public final class And: CombiningEvaluator {
public override init(_ evaluators: [Evaluator]) {
super.init(evaluators)
}
public override init(_ evaluators: Evaluator...) {
super.init(evaluators)
}
public override func matches(_ root: Element, _ node: Element) -> Bool {
for index in 0..<num {
let evaluator = evaluators[index]
do {
if (try !evaluator.matches(root, node)) {
return false
}
} catch {}
}
return true
}
public override func toString() -> String {
let array: [String] = evaluators.map { String($0.toString()) }
return StringUtil.join(array, sep: " ")
}
}
public final class Or: CombiningEvaluator {
/**
* Create a new Or evaluator. The initial evaluators are ANDed together and used as the first clause of the OR.
* @param evaluators initial OR clause (these are wrapped into an AND evaluator).
*/
public override init(_ evaluators: [Evaluator]) {
super.init()
if num > 1 {
self.evaluators.append(And(evaluators))
} else { // 0 or 1
self.evaluators.append(contentsOf: evaluators)
}
updateNumEvaluators()
}
override init(_ evaluators: Evaluator...) {
super.init()
if num > 1 {
self.evaluators.append(And(evaluators))
} else { // 0 or 1
self.evaluators.append(contentsOf: evaluators)
}
updateNumEvaluators()
}
override init() {
super.init()
}
public func add(_ evaluator: Evaluator) {
evaluators.append(evaluator)
updateNumEvaluators()
}
public override func matches(_ root: Element, _ node: Element) -> Bool {
for index in 0..<num {
let evaluator: Evaluator = evaluators[index]
do {
if (try evaluator.matches(root, node)) {
return true
}
} catch {}
}
return false
}
public override func toString() -> String {
return ":or\(evaluators.map {String($0.toString())})"
}
}
}