Clay Shell Version 18

Version 18 of the Clay Shell program is like the previous version except that (1) Clay command definitions are remembered for the session in which they are defined, thus forming a new vocabulary of terms, and (2) a command is added for displaying the names of the vocabulary of terms defined in the session.

Demos

java -jar ".../Clay18.jar" -h 300 -w 700 -c random

java -jar ".../Clay18.jar" -h 300 -w 700 -c random

Code

package clay18;

import java.awt.*;
import java.awt.event.*;
import java.util.StringTokenizer;

public class Main {
    
    <<<Just like in the previous version!>>>

}

class ClayFrame extends Frame  implements ActionListener {
  
    <<<Just like in the previous version!>>>
  
}

class Interpreter {
    
    private ClayFrame clayFrame;
    private Vocabulary vocabulary;
        
    public Interpreter(ClayFrame cf) {
        clayFrame = cf;
        establishQuotes();
        establishWords();
        vocabulary = new Vocabulary();
    }
    
    private String[] quotes;
    private String[] words;
    
    private void establishWords()
    {

        <<<Just like in the previous version!>>>

    }
    
    private void establishQuotes()
    {

        <<<Just like in the previous version!>>>

    }

    public void interpret(String input)
    {

        <<<Just like in the previous version!>>>

    }

    public void interpretCommand(String command)
    {
        if ( command.equals("red") ) {
            clayFrame.pa().setBackground(Color.red);
        } else if ( command.equals("yellow") ) {
            clayFrame.pa().setBackground(Color.yellow);
        } else if ( command.equals("green") ) {
            clayFrame.pa().setBackground(Color.green);
        } else if ( command.equals("random") ) {
            clayFrame.pa().setBackground(randomColor());
        } else if ( command.equals("clear") ) {
            clayFrame.ta().setText("");
        } else if ( command.equals("clean") ) {
            clayFrame.pa().setBackground(Color.white);
        } else if ( command.equals("quote") ) {
            interpretQuoteCommand();
        } else if ( command.equals("word") ) {
            interpretWordCommand();
        } else if ( command.equals("pause") ) {
            pause();
        } else if ( command.equals("defs") ) {
            clayFrame.ta().append(vocabulary.toString());
        } else if ( vocabulary.member(command) ) {
            Definition definition = vocabulary.search(command);
            interpretSimpleCommandSequence(definition.body());
        } else {
            clayFrame.ta().append("### Clay error:  Unrecognizable command: " + command + "\n");
        }
    }

    private void interpretQuoteCommand() {

        <<<Just like in the previous version!>>>

    }
       
    private void interpretWordCommand() {

        <<<Just like in the previous version!>>>

    }
       
    public Color randomColor() {

        <<<Just like in the previous version!>>>

    }

    private boolean isSimpleCommand(String input) {

        <<<Just like in the previous version!>>>

    }

    private boolean identifier(String input) {

        <<<Just like in the previous version!>>>

    }

    private boolean id(String input) {

        <<<Just like in the previous version!>>>

    }

    private boolean isAlphaNumeric(char ch) {

        <<<Just like in the previous version!>>>

    }

    private boolean alpha(char ch) {

        <<<Just like in the previous version!>>>

    }

    private boolean numeric(char ch) {

        <<<Just like in the previous version!>>>

    }

    private void interpretSimpleCommandSequence(String input) {

        <<<Just like in the previous version!>>>

    }

    private boolean isSimpleCommandSequence(String input) {

        <<<Just like in the previous version!>>>

    }
    
    private void pause() {

        <<<Just like in the previous version!>>>

    }    
    
    private boolean isClayDefinition(String input) {
        StringTokenizer st = new StringTokenizer(input);
        if ( st.countTokens() < 3 ) {
            return false;
        } else {
            String first = st.nextToken();
            String second = st.nextToken();
            String rest = rest(st);
            return identifier(first) & 
                    second.equals("=") & 
                    isSimpleCommandSequence(rest);
        }
    }
    
    private void interpretClayDefinition(String input) {
        StringTokenizer st = new StringTokenizer(input);
        String head = st.nextToken();
        String eqsign = st.nextToken();
        String body = rest(st);
        Definition definition = new Definition(head,body);
        try {
            vocabulary.add(definition);
        } catch (Exception ex) {
            clayFrame.ta().append("### Clay error:  vocabulary overflow");
            ex.printStackTrace();
        }
    }

    private String rest(StringTokenizer st) {

        <<<Just like in the previous version!>>>

    }

}

class Definition {

    <<<Just like in the previous version!>>>
    
}

class Vocabulary {

    private Definition[] definitions;
    private int nrDefs;
    
    public Vocabulary() {
        definitions = new Definition[1000];
        nrDefs = 0;
    }
    
    public String toString() {
        String result = "";
        for ( int i = 0; i < nrDefs; i++ ) {
            result = result + definitions[i].toString() + "\n";
        }
        return result;
    }    
    
    public void add(Definition def) throws Exception {
        if ( member(def.head()) ) {
            delete(def.head());
        }
        try {
            definitions[nrDefs] = def;
            nrDefs++;
        } catch ( Exception e ) {
            throw new Exception();
        }
    }

    public Definition search(String head) {
        for (int i = 0; i < nrDefs; i++) {
            if ( definitions[i].head().equals(head) ) {
                return definitions[i];
            }
        }
        return null;
    }
    
    private void delete(String head) throws Exception {
        int x = indexOf(head);
        if ( x == -1 ) {
            throw new Exception();
        } else {
            definitions[x] = definitions[nrDefs-1];
            nrDefs--;
        }
    }
    
    private int indexOf(String head) {
        for (int i = 0; i < nrDefs; i++) {
            if ( definitions[i].head().equals(head) ) {
                return i;
            }
        }
        return -1;
    }

    public boolean member(String head) {
        for (int i = 0; i < nrDefs; i++) {
            if ( definitions[i].head().equals(head) ) {
                return true;
            }
        }
        return false;
    }
    
}
Questions

  1. What is the new "featured" variable in this version?
  2. What is the new "featured" class in this version?
  3. What is the maximum number of definitions that can be stored in a Clay session?
  4. Define an interface called VocabularyADT which corresponds to the Vocabulary class.
  5. Is all of the functionality specified in the VocabularyADT interface used in the program?
  6. How is the method toString of the Vocabulary class used in this program?
  7. What is the method delete used for in the Vocabulary class.
  8. Is a Vocabulary object an example of a symbol table ?