/**
 * Exercise 11.2.1 Write a function repeatLoop, which should be applied as follows:
 *
 *    repeatLoop { command } ( condition )
 * 
 * Is there also a way to obtain a loop syntax like the following?
 * 
 *    repeatLoop { command } until ( condition )
*/

/*
  The repeatLoop is implemented as
*/
def repeatLoop(command: => Unit)(condition: => Boolen) =
  if (condition) {
    command
    repeatLoop (command) (condition)
  }

/*
  We can extend this command with until command
*/
def until(condition: => Boolean): Boolean = !condition

 

 

/**
 * Exercise 11.3.1 Write the implementation of orGate.
 */

/*
  Following the style of andGate, we have
*/
def orGate(a1: Wire, a2: Wire, output: Wire) {
  def orAction() {
    val a1Sig = a1.getSignal
    val a2Sig = a2.getSignal
    afterDelay(orGateDelay) {
      output setSignal (a1Sig | a2Sig)
    }
  }
  a1 addAction orAction
  a2 addAction orAction
}

 

 

/**
 * Exercise 11.3.2 Another way is to define an or-gate by a combination of
 * inverters and and gates. Define a function orGate in terms of andGate and
 * inverter. What is the delay time of this function?
 */

/*
  The book define the inverter function. So, we can use the De Morgan theorem
  to make a orGate in terms of andGate:
*/
def orGate(a1: Wire, a2: Wire, output: Wire) {
  inverter(a1, output)
  andGate(a1, a2, output)
}