CS 330 Lecture 18 – A Logo REPL
Agenda
- what ?s
- why write our own languages?
- program this
- building an interpreter…
- …with a REPL
TODO
- Nada. Though you wish to write more exam questions and post them in the comments. The more questions you come up with, the fewer I’ll come up with.
Program This
Imagine you can manipulate a turtle/robot/drone with a program. In particular, you can do the following to your controllee:
- move it forward
- turn it
- cause it to leave a trail
Write a little program to do something interesting. You pick the syntax.
Code
Logo.g4
grammar Logo;
program
: statement* EOF
;
statement
: command '\n'
;
command
: MOVE INT # Move
| TURN INT # Turn
| SLIME (ON | OFF) # Slime
;
MOVE : 'move';
TURN : 'turn';
SLIME : 'slime';
ON : 'on';
OFF : 'off';
INT : '-'? [0-9]+;
WHITESPACE : [ \t\r]+ -> skip;
makefile
Note to copy and pasters: makefile rules need to be indented with real tabs, not spaces.
ANTLR_JAR = $(HOME)/bin/antlr-4.0-complete.jar
ANTLR = java -jar $(ANTLR_JAR)
LogoParser.class: Logo.g4 makefile
$(ANTLR) Logo.g4
javac Logo*.java
Interpreter.class: LogoParser.class Interpreter.java
javac Interpreter.java
clean:
rm -f *.class Logo*.java *.tokens
Interpreter.java
import org.antlr.v4.runtime.*;
import java.util.ArrayList;
import java.io.IOException;
import org.antlr.v4.runtime.tree.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.AffineTransform;
public class Interpreter extends LogoBaseListener {
public static void main(String[] args) throws IOException {
ANTLRInputStream input = new ANTLRInputStream(System.in);
LogoLexer lexer = new LogoLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
LogoParser parser = new LogoParser(tokens);
ParseTree tree = parser.program();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(new Interpreter(500), tree);
}
/* ------------------------------------------------------------------------- */
private double x = 0.0;
private double y = 0.0;
private double theta = 0.0;
private boolean isLeaking = true;
public void exitMove(LogoParser.MoveContext context) {
double distance = Double.parseDouble(context.INT().getText());
double newX = distance * Math.cos(theta);
double newY = distance * Math.sin(theta);
display.addSegment(new Line2D.Double(x, y, newX, newY));
display.step();
x = newX;
y = newY;
}
public void exitTurn(LogoParser.TurnContext context) {
double angle = Double.parseDouble(context.INT().getText());
display.setCursor(0.0, 0.0, angle);
display.step();
}
/* ------------------------------------------------------------------------- */
private LogoDisplay display;
private int delay;
public Interpreter(int delay) {
JFrame frame = new JFrame("Logo");
display = new LogoDisplay();
frame.setContentPane(display);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
this.delay = delay;
display.step();
}
class LogoDisplay extends JPanel {
private ArrayList<Line2D.Double> segments;
private Line2D.Double arrowTop;
private Line2D.Double arrowBottom;
private double x;
private double y;
private double theta;
public LogoDisplay() {
segments = new ArrayList<Line2D.Double>();
arrowTop = new Line2D.Double(-10.0f, -5.0f, 0.0f, 0.0f);
arrowBottom = new Line2D.Double(-10.0f, 5.0f, 0.0f, 0.0f);
x = 0.0;
y = 0.0;
theta = 0.0;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
AffineTransform xform = g2.getTransform();
g2.translate(100, 100);
for (Line2D.Double segment : segments) {
g2.draw(segment);
}
g2.translate(x, y);
g2.rotate(theta);
g2.draw(arrowTop);
g2.draw(arrowBottom);
}
public void step() {
repaint();
try {
Thread.sleep(delay);
} catch (InterruptedException e) {}
}
public void setCursor(double x, double y, double theta) {
this.x = x;
this.y = y;
this.theta = theta;
}
public void addSegment(Line2D.Double segment) {
segments.add(segment);
}
}
}
Haiku
Don’t reinvent wheels
Bow before the pioneers
Their third-gen wheels rock
Bow before the pioneers
Their third-gen wheels rock