CS 330 Lecture 29 – Modeling a Program
Agenda
- what ?s
- model this
- a model for Logo
Model This
Express the following in superfast-to-process tree form:
$a = 5 * ($a + 7)
move 10
rotate 45
move 5
repeat 4
move 10
rotate 90
end
Code
Block.java
package logo330;
import java.util.ArrayList;
public class Block {
private ArrayList<Command> commands = new ArrayList<Command>();
public void execute(Environment env) {
for (Command command : commands) {
command.execute(env);
}
}
public void add(Command command) {
commands.add(command);
}
}
Command.java
package logo330;
public abstract class Command {
public abstract void execute(Environment env);
}
CommandListener.java
package logo330;
public interface CommandListener {
public void onPostCommand();
}
CommandMove.java
package logo330;
import java.awt.geom.Line2D;
public class CommandMove extends Command {
private Expression expr;
public CommandMove(Expression expr) {
this.expr = expr;
}
@Override
public void execute(Environment env) {
double newX = env.x + Math.cos(env.theta) * expr.evaluate(env);
double newY = env.y + Math.sin(env.theta) * expr.evaluate(env);
synchronized (env.segments) {
env.segments.add(new Line2D.Double(env.x, env.y, newX, newY));
}
env.x = newX;
env.y = newY;
env.listener.onPostCommand();
}
}
CommandRotate.java
package logo330;
import java.awt.geom.Line2D;
public class CommandRotate extends Command {
private Expression expr;
public CommandRotate(Expression expr) {
this.expr = expr;
}
@Override
public void execute(Environment env) {
env.theta += Math.toRadians(expr.evaluate(env));
env.listener.onPostCommand();
}
}
Environment.java
package logo330;
import java.awt.geom.Line2D;
import java.util.ArrayList;
public class Environment {
public double x = 0.0;
public double y = 0.0;
public double theta = 0.0;
public ArrayList<Line2D.Double> segments = new ArrayList<Line2D.Double>();
public CommandListener listener = null;
}
Expression.java
package logo330;
public abstract class Expression {
public abstract double evaluate(Environment env);
}
ExpressionLiteral.java
package logo330;
public class ExpressionLiteral extends Expression {
private double value;
public ExpressionLiteral(double value) {
this.value = value;
}
public double evaluate(Environment env) {
return value;
}
}
LogoVirtualMachine.java
package logo330;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LogoVirtualMachine implements CommandListener {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
new LogoVirtualMachine();
}
private JFrame display;
private JPanel panel;
private int delay = 500;
public LogoVirtualMachine() {
Environment env = new Environment();
env.listener = this;
panel = new LogoDisplay(env);
display = new JFrame("Logo");
display.setContentPane(panel);
display.setSize(1200, 700);
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
display.setVisible(true);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
Block main = new Block();
main.add(new CommandMove(new ExpressionLiteral(24.0)));
main.add(new CommandRotate(new ExpressionLiteral(90.0)));
main.add(new CommandMove(new ExpressionLiteral(24.0)));
main.add(new CommandRotate(new ExpressionLiteral(90.0)));
main.add(new CommandMove(new ExpressionLiteral(24.0)));
main.add(new CommandRotate(new ExpressionLiteral(90.0)));
main.add(new CommandMove(new ExpressionLiteral(24.0)));
main.add(new CommandRotate(new ExpressionLiteral(90.0)));
main.execute(env);
}
public void onPostCommand() {
pause();
panel.paintImmediately(0, 0, panel.getWidth(), panel.getHeight());
}
private void pause() {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
}
}
class LogoDisplay extends JPanel {
private Line2D.Double arrowTop;
private Line2D.Double arrowBottom;
private Environment env;
public LogoDisplay(Environment env) {
this.env = env;
arrowTop = new Line2D.Double(-10.0f, -5.0f, 0.0f, 0.0f);
arrowBottom = new Line2D.Double(-10.0f, 5.0f, 0.0f, 0.0f);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
AffineTransform xform = g2.getTransform();
g2.translate(getWidth() / 2, getHeight() / 2);
synchronized (env.segments) {
for (Line2D.Double segment : env.segments) {
g2.draw(segment);
}
}
g2.translate(env.x, env.y);
g2.rotate(env.theta);
g2.draw(arrowTop);
g2.draw(arrowBottom);
g2.setTransform(xform);
}
}
}
Haiku
Propaganda talks
The more languages we have
The smaller the mobs
The more languages we have
The smaller the mobs