Download: jar file
This verison of the gates1 program
uses a TextAreaPrintStream class for output. It can now
be run as an applet or window application.
This version also illustrates the use of parameter fields for applets:
<applet code="gates1.class" archive="gates1.jar" width=640 height=200> <param name="url" value="https://johnloomis.org/ece538/notes/gates1/logic1.net"> </applet>
See line 139 to see how the value of the parameter "url" is read.
gates1.javaCircuit.javaTextAreaPrintStream.javagates1.java001: // gates1.java
002:
003: import java.io.*;
004: import java.net.*;
005: import java.util.ArrayList;
006: import java.awt.EventQueue;
007: import javax.swing.*;
008:
009:
010: // This class is a modified version of netlist3.java
011: class Process {
012: JTextArea area;
013: TextAreaPrintStream out;
014: String filename;
015: boolean isURL;
016: Circuit ckt;
017:
018: Process(String filename)
019: {
020: this.filename = filename;
021: area = new JTextArea(16,70);
022: out = new TextAreaPrintStream(area,System.out);
023: isURL = false;
024:
025: // out = System.out;
026: }
027:
028: public void run()
029: {
030: InputStream instream;
031: BufferedReader in;
032:
033: out.println("Filename: " + filename);
034:
035: try {
036: if (isURL) {
037: URL url = new URL(filename);
038: instream = url.openStream();
039: }
040: else instream = new FileInputStream(filename);
041: in = new BufferedReader(new InputStreamReader(instream));
042: ckt = new Circuit();
043: ckt.read(in,out);
044: in.close();
045: out.println("\nDevice list:\n");
046: ckt.list_devices(out);
047: ckt.build_node_list();
048: out.println("\nNode list:\n");
049: ckt.list_nodes(out);
050: if (ckt.inputs!=null || ckt.outputs!= null) out.println("\n\n");
051: if (ckt.inputs!=null) show("inputs",ckt.inputs);
052: if (ckt.outputs!=null) show("outputs",ckt.outputs);
053: showTable();
054: } catch (IOException e) {
055: out.println( e);
056: }
057: }
058:
059: void show(String name, String vals[])
060: {
061: int j, nvals;
062: String str = name;
063: for (String val: vals) str += "\t" + val;
064: out.println(str);
065: }
066:
067: void showTable()
068: {
069: String [] inputs = ckt.inputs;
070: String [] outputs = ckt.outputs;
071: int ninp = inputs.length;
072: int noup = outputs.length;
073: int ncases = (int) Math.pow(2,ninp);
074: int j, k, v;
075: String str = "";
076: out.println("\n");
077: for (j=0; j<ninp; j++) {
078: if (j>0) str += "\t" + inputs[j];
079: else str = inputs[j];
080: }
081: for (j=0; j<noup; j++) str += "\t" + outputs[j];
082: out.println(str + "\tcycles\tmax_changed");
083:
084: Node [] input_nodes = new Node[ninp];
085: ArrayList<Node> changed_in = new ArrayList<Node>();
086: ArrayList<Node> changed_out = new ArrayList<Node>();
087: for (j=0; j<ninp; j++) {
088: Node node = ckt.find_node(inputs[j]);
089: if (node==null) out.printf("node %s not found\n",inputs[j]);
090: input_nodes[j] = node;
091: }
092:
093: Node [] output_nodes = new Node[noup];
094: for (j=0; j<noup; j++) {
095: Node node = ckt.find_node(outputs[j]);
096: if (node==null) out.printf("node %s not found\n",outputs[j]);
097: output_nodes[j] = node;
098: }
099: // cycle through the possible input values (for a truth table)
100: for (k=0; k<ncases; k++) {
101: for (j = 0; j<ninp; j++) {
102: v = (k>>(ninp-1-j))&1;
103: if (j>0) str += "\t" + v;
104: else str = "" + v;
105: Node node = input_nodes[j];
106: node.setValue(v);
107: changed_in.add(node);
108:
109: }
110:
111: // evaluate the circuit until nothing changes
112: int ncycles, change;
113: ncycles = 0;
114: change = ckt.eval(changed_in,changed_out);
115: int max_change = change;
116: while (change>0) {
117: ncycles++;
118: changed_in.clear();
119: changed_in.addAll(changed_out);
120: changed_out.clear();
121: change = ckt.eval(changed_in,changed_out);
122: if (change>max_change) max_change = change;
123: }
124:
125: // print the output values
126: for (j=0; j<noup; j++) str += "\t" + output_nodes[j].getLogic();
127: out.println(str + "\t" + ncycles + "\t" + max_change);
128: }
129: }
130: }
131:
132: public class gates1 extends JApplet {
133:
134: public void init()
135: {
136: EventQueue.invokeLater(new Runnable() {
137: public void run()
138: {
139: String url = getParameter("url");
140: Process proc = new Process(url);
141: proc.isURL = true;
142: add(new JScrollPane(proc.area));
143: proc.run();
144: }
145: });
146: }
147:
148: public static void main(String[] args)
149: {
150: String filename;
151:
152: if (args.length < 1) {
153: filename = "logic1.net";
154: }
155: else filename = args[0];
156: final Process proc = new Process(filename);
157:
158: EventQueue.invokeLater(new Runnable() {
159: public void run()
160: {
161: JFrame frame = new JFrame("Gates Version 1");
162: frame.add(new JScrollPane(proc.area));
163: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
164: frame.pack();
165: //frame.setSize(640,200);
166: frame.setVisible(true);
167: proc.run();
168: }
169: });
170: }
171: }
Circuit.java001: import java.io.*;
002: import java.util.ArrayList;
003:
004: public class Circuit
005: {
006: String name;
007: Node ref;
008: ArrayList<Node> nodes;
009: ArrayList<Device> devices;
010: String [] inputs;
011: String [] outputs;
012:
013: Circuit()
014: {
015: ref = new Node("0");
016: devices = new ArrayList<Device>();
017: nodes = new ArrayList<Node>();
018: }
019:
020: public void read(BufferedReader inr, PrintStream out) {
021: LineNumberReader in = new LineNumberReader(inr);
022: boolean done = false;
023: while (!done) {
024: int n = in.getLineNumber();
025: try {
026: String inp = in.readLine();
027: if (inp==null) break;
028: out.println("Line " + n + ": " + inp);
029: String [] str = inp.split("%"); // terminate at comment character
030: String [] tokens = str[0].split("\\s+");
031: if (tokens.length>1) {
032: // This version just does gates
033: Device d = Gate.getNewDevice(tokens[0]);
034: if (d!=null) {
035: d.parse(tokens);
036: devices.add(d);
037: }
038: else if (tokens[0].equals("inputs")) inputs = saveTokens(tokens);
039: else if (tokens[0].equals("outputs")) outputs = saveTokens(tokens);
040: else out.println("Device not recognized: " + tokens[0] );
041: }
042: }
043: catch (IOException e) {
044: out.println(e);
045: }
046: }
047: out.println();
048: }
049:
050: String [] saveTokens(String tokens[])
051: {
052: int i, ntokens;
053: ntokens = tokens.length;
054: String [] list = new String[ntokens-1];
055: for (i=1; i<ntokens; i++) list[i-1] = tokens[i];
056: return list;
057: }
058:
059: Node find_node(String str)
060: {
061: int ncount = nodes.size();
062: for (int j=0; j<ncount; j++) {
063: Node node = nodes.get(j);
064: if (node.name.equals(str)) return node;
065: }
066: return null;
067: }
068:
069:
070: int add_node(String str, Device dev)
071: {
072: int i;
073: Node node;
074: int ncount = nodes.size();
075: for (i=0; i<ncount; i++) {
076: node = nodes.get(i);
077: if (node.name.equals(str)) {
078: node.devices.add(dev);
079: return i;
080: }
081: }
082: node = new Node(str);
083: nodes.add(node);
084: node.devices.add(dev);
085: return ncount;
086: }
087:
088: void build_node_list()
089: {
090: int i, j;
091: Device dev;
092: int ndevices = devices.size();
093: for (i=0; i<ndevices; i++) {
094: dev = devices.get(i);
095: int nodecount = dev.nodes.length;
096: for (j=0; j<nodecount; j++) dev.ndx[j] = add_node(dev.nodes[j],dev);
097: }
098: }
099:
100: void list_nodes(PrintStream out)
101: {
102: for (Node node: nodes) out.println(node);
103: /*
104: int i;
105: int ncount = nodes.size();
106: for (i=0; i<ncount; i++) {
107: Node node = nodes.get(i);
108: out.printf("%d\t %s\n",i,node);
109: }
110: */
111: }
112:
113:
114: void list_devices(PrintStream out)
115: {
116: for (Device d: devices) out.println(d);
117: }
118:
119: int eval(ArrayList<Node> changed_in, ArrayList<Node> changed_out)
120: {
121: ArrayList<Gate> devices = new ArrayList<Gate>(0);
122: Gate gate;
123: for (Node node: changed_in) {
124: for (Device dev: node.devices) {
125: gate = (Gate) dev;
126: // we only evaluate gates
127: if (!dev.getClass().isInstance(gate)) continue;
128: if (!devices.contains(gate)) devices.add(gate);
129: }
130: }
131: for (Gate dev: devices) dev.eval(nodes,changed_out);
132: return changed_out.size();
133: }
134: }
TextAreaPrintStream.java01: /**
02: * Class TextAreaPrintStream
03: * extends PrintStream.
04: * A custom made PrintStream which overrides methods println(String)
05: * and print(String).
06: * Thus, when the out stream is set as this PrintStream (with System.setOut
07: * method), all calls to System.out.println(String) or System.out.print(String)
08: * will result in an output stream of characters in the JTextArea given as an
09: * argument of the constructor of the class.
10: **/
11:
12: import java.io.*;
13: import javax.swing.*;
14:
15: public class TextAreaPrintStream extends PrintStream {
16:
17: //The JTextArea to wich the output stream will be redirected.
18: private JTextArea textArea;
19:
20:
21: /**
22: * Method TextAreaPrintStream
23: * The constructor of the class.
24: * @param the JTextArea to wich the output stream will be redirected.
25: * @param a standard output stream (needed by super method)
26: **/
27: public TextAreaPrintStream(JTextArea area, OutputStream out) {
28: super(out);
29: textArea = area;
30: }
31:
32: /**
33: * Method println
34: * @param the String to be output in the JTextArea textArea (private
35: * attribute of the class).
36: * After having printed such a String, prints a new line.
37: **/
38: public void println(String string) {
39: textArea.append(string+"\n");
40: }
41:
42: public void println() {
43: textArea.append("\n");
44: }
45:
46: public void println(Object obj) {
47: textArea.append(obj.toString()+"\n");
48: }
49:
50:
51:
52: /**
53: * Method print
54: * @param the String to be output in the JTextArea textArea (private
55: * attribute of the class).
56: **/
57: public void print(String string) {
58: textArea.append(string);
59: }
60:
61: public void print(Object obj) {
62: textArea.append(obj.toString());
63: }
64: }
Maintained by John Loomis, updated Wed Mar 26 11:16:28 2008