Release v3.0

This commit is contained in:
Koen Yskout
2018-04-17 13:54:17 +02:00
parent 295c510d73
commit d5cbb646ed
81 changed files with 5752 additions and 15 deletions

3
OGP1718-Worms/src-provided/worms/Worms.java Normal file → Executable file
View File

@@ -22,6 +22,9 @@ public class Worms {
options.randomSeed = randomSeed;
} else if ("-clickselect".equals(arg)) {
options.enableClickToSelect = true;
} else if ("-program".equals(arg)) {
String program = args[++i];
options.programFile = program;
}
}

138
OGP1718-Worms/src-provided/worms/facade/IFacade.java Normal file → Executable file
View File

@@ -2,7 +2,10 @@ package worms.facade;
import java.math.BigInteger;
import java.util.*;
import worms.internal.gui.game.IActionHandler;
import worms.model.*;
import worms.programs.IProgramFactory;
import worms.util.ModelException;
import worms.util.MustNotImplementException;
@@ -356,6 +359,7 @@ public interface IFacade {
default void fall(Worm worm) throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Return the time needed by the given worm to jump to the nearest position
* adjacent to impassable terrain.
@@ -380,7 +384,17 @@ public interface IFacade {
*/
void jump(Worm worm, double timeStep) throws ModelException;
/**
* Make the given worm eat a portion of food.
*/
void eat(Worm worm) throws ModelException;
/**
* Have the give worm fire a projectile.
* - The method must return the projectile that has been fired.
*/
Projectile fire(Worm worm) throws ModelException;
/************
* FOOD
@@ -426,11 +440,76 @@ public interface IFacade {
*/
World getWorld(Food food) throws ModelException;
/**
* Return whether or not the given portion of food is poisonous.
*/
boolean isPoisonous(Food food) throws ModelException;
/**
* Poison the given portion of food.
*/
void poison(Food food) throws ModelException;
/*************
* PROJECTILE
*************/
/**
* Make the given worm eat a portion of food.
* Check whether the given projectile is terminated.
*/
public void eat(Worm worm);
boolean isTerminated(Projectile projectile) throws ModelException;
/**
* Return the current orientation of the given projectile (in radians).
*/
double getOrientation(Projectile projectile) throws ModelException;
/**
* Return the current location of the given projectile.
* - The resulting array contains the the x-coordinate of the given projectile
* followed by its y-coordinate.
*/
double[] getLocation(Projectile projectile) throws ModelException;
/**
* Return the radius of the given projectile.
*/
double getRadius(Projectile projectile);
/**
* Return the number of hit points of the given projectile.
*/
int getNbHitPoints(Projectile projectile) throws ModelException;
/**
* Returns the location on the jump trajectory of the given projectile
* after a time t.
* - The resulting location is an array with two elements,
* with the first element being the x-coordinate and the
* second element the y-coordinate.
*/
double[] getJumpStep(Projectile projectile, double elapsedTime);
/**
* Return the time needed by the given projectile to jump to the nearest
* location at which the projectile hits impassable terrain or a worm.
* - deltaT determines the resolution to be used in successive steps of the jump.
*/
double getJumpTime(Projectile projectile, double jumpTimeStep) throws ModelException;
/**
* Make the given projectile jump using the given time step.
* - The given time step determines a time interval during which
* you may assume that the projectile will not hit impassable
* terrain nor a worm.
*/
void jump(Projectile projectile, double jumpTimeStep) throws ModelException;
/********
* TEAM
@@ -523,4 +602,59 @@ public interface IFacade {
throw new MustNotImplementException();
}
/**********
* PROGRAMS
**********/
/**
* Return the program loaded on the given worm.
*/
Program getWormProgram(Worm worm) throws ModelException;
/**
* Load the given program on the given worm.
*
* While executing the program, the worm must invoke the methods corresponding
* to actions through the provided ActionHandler object (e.g., actionHandler.jump(this),
* actionHandler.turn(this, 0.2), etc.) rather than invoking them directly (e.g., this.jump()).
* This executes the action as if a human player has initiated it, so the GUI can update itself.
* The GUI will also invoke the corresponding method on the worm through the facade.
*/
public void loadProgramOnWorm(Worm worm, Program program, IActionHandler actionHandler) throws ModelException;
/**
* Execute the program loaded on the given worm.
* The worm is positioned in some world. Returns null if the program
* is not completely executed. Otherwise, returns the objects that have been
* printed.
*
* This method is only used in the tests. The GUI never calls this method;
* you should execute the program when the worm is activated.
*/
public List<Object> executeProgram(Worm worm) throws ModelException;
/**
* Creates a new program factory.
*/
public IProgramFactory<?, ?, ?, ? extends Program> createProgramFactory() throws ModelException;
/*********
* WIZARD
*********/
/**
* Have the wizard cast a spell over two randomly slected game objects in the given
* world.
*/
void castSpell(World world) throws ModelException;
}

View File

View File

View File

View File

@@ -26,4 +26,11 @@ public class GUIOptions {
*/
public boolean enableClickToSelect = false;
/**
* The program that is executed by computer-controlled worms.
* Default: "programs/program.txt"
*
* Can also be set from the command line with the -program argument
*/
public String programFile = "programs/program.txt";
}

View File

View File

View File

View File

View File

View File

View File

@@ -5,11 +5,13 @@ import java.util.concurrent.Executors;
import worms.facade.IFacade;
import worms.internal.gui.GameState;
import worms.internal.gui.game.commands.ActivateWizard;
import worms.internal.gui.game.commands.AddNewFood;
import worms.internal.gui.game.commands.AddNewTeam;
import worms.internal.gui.game.commands.AddNewWorm;
import worms.internal.gui.game.commands.Command;
import worms.internal.gui.game.commands.Eat;
import worms.internal.gui.game.commands.Fire;
import worms.internal.gui.game.commands.Jump;
import worms.internal.gui.game.commands.Move;
import worms.internal.gui.game.commands.Rename;
@@ -88,8 +90,14 @@ class DefaultActionHandler implements IActionHandler {
executeCommand(new Rename(getFacade(), worm, newName, getScreen()));
}
public void eat(Worm worm) {
executeCommand(new Eat(getFacade(), worm, getScreen()));
@Override
public boolean eat(Worm worm) {
return executeCommand(new Eat(getFacade(), worm, getScreen()));
}
@Override
public boolean fire(Worm worm) {
return executeCommand(new Fire(getFacade(), worm, getScreen()));
}
public void selectNextWorm() {
@@ -100,8 +108,8 @@ class DefaultActionHandler implements IActionHandler {
executeCommand(new StartGame(getFacade(), getScreen()));
}
public void addNewWorm() {
executeCommand(new AddNewWorm(getFacade(), getScreen()));
public void addNewWorm(boolean withProgram) {
executeCommand(new AddNewWorm(getFacade(), withProgram, getScreen()));
}
public void addEmptyTeam(String name) {
@@ -111,5 +119,9 @@ class DefaultActionHandler implements IActionHandler {
public void addNewFood() {
executeCommand(new AddNewFood(getFacade(), getScreen()));
}
public void activateWizard() {
executeCommand(new ActivateWizard(getFacade(), getScreen()));
}
}

View File

@@ -14,6 +14,7 @@ import worms.model.Worm;
* <li>shows periodic updates on the GUI (such as jump animations)
* <li>eventually calls the corresponding facade methods, exactly like what
* happens with a human player
* <li>makes sure a worm will fall after moving
* <li>returns true if the action has been completed successfully; false
* otherwise
* </ul>
@@ -29,6 +30,10 @@ public interface IActionHandler {
public boolean move(Worm worm);
public boolean jump(Worm worm);
public boolean eat(Worm worm);
public boolean fire(Worm worm);
/**
* Print a message on the screen for a short amount of time.

View File

View File

@@ -224,6 +224,14 @@ public class PlayGameScreen extends Screen {
}
}
public void fire() {
Worm worm = getSelectedWorm();
if (worm != null) {
userActionHandler.fire(worm);
}
}
public void turn(double angle) {
Worm worm = getSelectedWorm();
@@ -397,7 +405,11 @@ public class PlayGameScreen extends Screen {
}
public void addPlayerControlledWorm() {
userActionHandler.addNewWorm();
userActionHandler.addNewWorm(false);
}
public void addComputerControlledWorm() {
userActionHandler.addNewWorm(true);
}
public void addFood() {
@@ -445,4 +457,8 @@ public class PlayGameScreen extends Screen {
return programActionHandler;
}
public void activateWizard() {
userActionHandler.activateWizard();
}
}

View File

@@ -17,6 +17,7 @@ import worms.internal.gui.GUIUtils;
import worms.internal.gui.GameState;
import worms.internal.gui.Level;
import worms.internal.gui.game.sprites.FoodSprite;
import worms.internal.gui.game.sprites.ProjectileSprite;
import worms.internal.gui.game.sprites.WormSprite;
import worms.model.World;
import worms.util.ModelException;
@@ -102,9 +103,18 @@ public class PlayGameScreenPainter extends AbstractPainter<PlayGameScreen> {
paintWorm(sprite);
}
for (ProjectileSprite sprite : getScreen().getSpritesOfType(
ProjectileSprite.class)) {
paintProjectile(sprite);
}
this.currentGraphics = null;
}
protected void paintProjectile(ProjectileSprite sprite) {
sprite.draw(currentGraphics);
}
protected void paintFood(FoodSprite sprite) {
sprite.draw(currentGraphics);
}

View File

View File

@@ -0,0 +1,29 @@
package worms.internal.gui.game.commands;
import worms.facade.IFacade;
import worms.internal.gui.game.PlayGameScreen;
import worms.internal.gui.messages.MessageType;
import worms.util.ModelException;
public class ActivateWizard extends InstantaneousCommand {
public ActivateWizard(IFacade facade,
PlayGameScreen screen) {
super(facade, screen);
}
@Override
protected boolean canStart() {
return true;
}
@Override
protected void doStartExecution() {
try {
getFacade().castSpell(getWorld());
getScreen().addMessage("The wizard has done wizardry things!", MessageType.INFO);
} catch (ModelException e) {
getScreen().addMessage("The wizard could not cast its spell :(", MessageType.ERROR);
}
}
}

View File

@@ -1,21 +1,34 @@
package worms.internal.gui.game.commands;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Random;
import worms.facade.IFacade;
import worms.internal.gui.GUIUtils;
import worms.internal.gui.WormsGUI;
import worms.internal.gui.game.PlayGameScreen;
import worms.internal.gui.messages.MessageType;
import worms.model.Program;
import worms.model.Team;
import worms.model.Worm;
import worms.programs.IProgramFactory;
import worms.programs.ParseOutcome;
import worms.programs.ProgramParser;
import worms.util.ModelException;
public class AddNewWorm extends InstantaneousCommand {
private static final double MIN_RADIUS = 0.25;
private static final double MAX_RADIUS = Math.pow(2, 1.0/3.0) * MIN_RADIUS;
public AddNewWorm(IFacade facade, PlayGameScreen screen) {
private static final double MAX_RADIUS = Math.pow(2, 1.0 / 3.0) * MIN_RADIUS;
private boolean withProgram;
public AddNewWorm(IFacade facade, boolean withProgram, PlayGameScreen screen) {
super(facade, screen);
this.withProgram = withProgram;
}
@Override
@@ -36,10 +49,82 @@ public class AddNewWorm extends InstantaneousCommand {
double direction = random.nextDouble() * 2 * Math.PI;
Team team = getScreen().getLastCreatedTeam();
getFacade().createWorm(getWorld(), p, direction, radius, name, team);
Worm worm = getFacade().createWorm(getWorld(), p, direction, radius, name, team);
if (withProgram) {
loadProgram(worm);
}
} catch (ModelException e) {
e.printStackTrace();
getScreen().addMessage("Could not create worm", MessageType.ERROR);
}
}
private void loadProgram(Worm worm) {
String programText = readProgramText();
if (programText != null) {
IProgramFactory<?, ?, ?, ? extends Program> factory = getFacade().createProgramFactory();
ProgramParser<?, ?, ?, ? extends Program> parser = ProgramParser.create(factory);
ParseOutcome<? extends Program> outcome = parser.parseString(programText);
if (outcome != null) {
if (outcome.isSuccess()) {
Program program = outcome.getSuccessValue();
getFacade().loadProgramOnWorm(worm, program, getScreen().getProgramActionHandler());
} else {
List<String> errors = outcome.getFailValue();
String msg = "Parsing failed\nwith the following errors:\n";
for (String error : errors) {
msg += error + "\n";
}
cancelExecution();
getGUI().showError(msg);
return;
}
}
} else {
cancelExecution();
getGUI().showError("Could not parse program");
}
}
private WormsGUI getGUI() {
return getScreen().getGUI();
}
protected String readProgramText() {
InputStream stream;
try {
stream = GUIUtils.openResource(getGUI().getOptions().programFile);
} catch (IOException e) {
e.printStackTrace();
getGUI().showError(e.getMessage());
return null;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder programText = new StringBuilder();
String line;
try {
line = reader.readLine();
while (line != null) {
programText.append(line);
programText.append("\n");
line = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
cancelExecution(e);
return null;
} finally {
try {
reader.close();
} catch (IOException e) {
// I don't care
}
}
return programText.toString();
}
}

View File

View File

@@ -0,0 +1,83 @@
package worms.internal.gui.game.commands;
import worms.facade.IFacade;
import worms.internal.gui.GUIConstants;
import worms.internal.gui.game.PlayGameScreen;
import worms.internal.gui.game.sprites.ProjectileSprite;
import worms.internal.gui.messages.MessageType;
import worms.model.Projectile;
import worms.model.Worm;
import worms.util.ModelException;
public class Fire extends Command {
private final Worm worm;
private Projectile projectile;
private double totalDuration;
private boolean hasJumped;
public Fire(IFacade facade, Worm worm, PlayGameScreen screen) {
super(facade, screen);
this.worm = worm;
}
@Override
protected boolean canStart() {
return worm != null;
}
@Override
protected void doStartExecution() {
try {
projectile = getFacade().fire(worm);
if (projectile != null) {
totalDuration = getFacade().getJumpTime(projectile, GUIConstants.JUMP_TIME_STEP);
ProjectileSprite sprite = new ProjectileSprite(getScreen(), projectile);
sprite.update();
getScreen().addSprite(sprite);
} else {
cancelExecution();
}
} catch (ModelException e) {
e.printStackTrace();
cancelExecution();
}
}
@Override
protected void afterExecutionCompleted() {
super.afterExecutionCompleted();
ProjectileSprite sprite = getScreen().getSpriteOfTypeFor(ProjectileSprite.class, projectile);
if (sprite != null) {
sprite.setDoneMoving();
}
}
@Override
protected void afterExecutionCancelled(Throwable e) {
getScreen().addMessage("This worm cannot shoot :(" + (e != null ? "\n" + e.getMessage() : ""),
MessageType.ERROR);
}
@Override
protected void doUpdate(double dt) {
try {
if (getElapsedTime() >= totalDuration) {
if (!hasJumped) {
hasJumped = true;
getFacade().jump(projectile, GUIConstants.JUMP_TIME_STEP);
completeExecution();
}
} else {
ProjectileSprite sprite = getScreen().getSpriteOfTypeFor(ProjectileSprite.class, projectile);
double[] xy = getFacade().getJumpStep(projectile, getElapsedTime());
sprite.setCenterLocation(getScreen().getScreenX(xy[0]), getScreen().getScreenY(xy[1]));
}
} catch (ModelException e) {
e.printStackTrace();
cancelExecution();
}
}
}

View File

View File

View File

@@ -24,6 +24,7 @@ public class StartGame extends InstantaneousCommand {
protected void afterExecutionCancelled(Throwable e) {
if (e != null) {
getScreen().addMessage("Cannot start the game: " + e.getMessage(), MessageType.ERROR);
e.printStackTrace();
} else {
getScreen().addMessage("Cannot start the game without worms", MessageType.ERROR);
}

View File

View File

@@ -55,6 +55,14 @@ public class DefaultInputMode extends InputMode<PlayGameScreen> {
case 'E':
getScreen().eat();
break;
case 'f':
case 'F':
getScreen().fire();
break;
case 's':
case 'S':
getScreen().activateWizard();
break;
}
}

View File

@@ -24,6 +24,10 @@ public class SetupInputMode extends InputMode<PlayGameScreen> {
case 'W':
getScreen().addPlayerControlledWorm();
break;
case 'c':
case 'C':
getScreen().addComputerControlledWorm();
break;
case 'f':
case 'F':
getScreen().addFood();
@@ -49,7 +53,12 @@ public class SetupInputMode extends InputMode<PlayGameScreen> {
getScreen()
.showInstructions(
g,
"Press\n'T' to create a new team\n'W' to add a new worm\n'F' to add food\n'S' to start the game");
"Press\n"
+ "'T' to create a new team\n"
+ "'W' to add a new player-controlled worm\n"
+ "'C' to add a new computer-controlled worm\n"
+ "'F' to add food\n"
+ "'S' to start the game");
}
}

View File

@@ -1,5 +1,8 @@
package worms.internal.gui.game.sprites;
import java.awt.Image;
import java.awt.image.BufferedImage;
import worms.internal.gui.game.ImageSprite;
import worms.internal.gui.game.PlayGameScreen;
import worms.model.Food;
@@ -12,10 +15,22 @@ public class FoodSprite extends ImageSprite<Food> {
private final Food food;
private double radius;
private boolean poisonous = false;
// original image, at original scale
private final BufferedImage originalPoisonousImage;
// only created when scale != 1.0
private BufferedImage scaledPoisonousImage;
public FoodSprite(PlayGameScreen screen, Food food) {
super(screen, "images/burger.png");
this.food = food;
// constraint: must have same dimensions as original image
// constraint: does not respect hflipping
this.originalPoisonousImage = loadImage("images/burger-poisonous.png");
this.scaledPoisonousImage = this.originalPoisonousImage;
update();
}
@@ -45,9 +60,52 @@ public class FoodSprite extends ImageSprite<Food> {
setScale(scaleFactor);
}
@Override
public void setScale(double newScale) {
double oldScale = getScale();
super.setScale(newScale);
if (newScale == oldScale) {
return;
}
if (newScale != 1.0) {
this.scaledPoisonousImage = toBufferedImage(originalPoisonousImage.getScaledInstance(
(int) (newScale * originalPoisonousImage.getWidth()),
(int) (newScale * originalPoisonousImage.getHeight()),
Image.SCALE_SMOOTH));
} else {
this.scaledPoisonousImage = originalPoisonousImage;
}
}
@Override
protected Image getImageToDraw() {
if (isPoisonous()) {
return scaledPoisonousImage;
} else {
return super.getImageToDraw();
}
}
public synchronized double getRadius() {
return radius;
}
public synchronized boolean isPoisonous() {
return poisonous;
}
public void setPoisonous(boolean poisonous) {
this.poisonous = poisonous;
}
@Override
public synchronized void update() {
setPoisonous(getFacade().isPoisonous(getFood()));
setRadius(getFacade().getRadius(getFood()));
double[] xy = getFacade().getLocation(getFood());
setCenterLocation(getScreen().getScreenX(xy[0]), getScreen().getScreenY(xy[1]));
@@ -67,8 +125,5 @@ public class FoodSprite extends ImageSprite<Food> {
return !getFacade().isTerminated(food);
}
public synchronized double getRadius() {
return radius;
}
}

View File

@@ -0,0 +1,143 @@
package worms.internal.gui.game.sprites;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import worms.internal.gui.GUIUtils;
import worms.internal.gui.game.PlayGameScreen;
import worms.internal.gui.game.Sprite;
import worms.model.Projectile;
public class ProjectileSprite extends Sprite<Projectile> {
private static final int MIN_DISPLAY_SIZE = 3; // pixels
private static final int MAX_DISPLAY_SIZE = 10; // pixels
private static final int DISPLAY_SCALE = 10;
private static final int NB_HISTORY = 15;
private static final Color[] colors = new Color[NB_HISTORY];
static {
for (int i = 0; i < colors.length; i++) {
float t = (float) i / colors.length;
colors[i] = new Color(1.0F, (1 - t), 0, 0.8F);
}
}
private final Projectile projectile;
private double sizeInPixels;
@SuppressWarnings("serial")
private static class LimitedQueue<E> extends LinkedList<E> {
private int limit;
public LimitedQueue(int limit) {
this.limit = limit;
}
@Override
public boolean add(E o) {
boolean result = super.add(o);
while (size() > limit) {
super.remove();
}
return result;
}
}
private final List<double[]> lastLocations = Collections.synchronizedList(new LimitedQueue<double[]>(
NB_HISTORY));
private boolean moving;
public ProjectileSprite(PlayGameScreen screen, Projectile projectile) {
super(screen);
this.projectile = projectile;
this.moving = true;
}
@Override
public synchronized void draw(Graphics2D g) {
if (moving) {
for (int i = 0; i < lastLocations.size(); i++) {
double[] loc = lastLocations.get(i);
g.setColor(colors[i]);
double t = (double) (i + 1) / lastLocations.size();
double size = sizeInPixels * t * t * t;
g.fill(GUIUtils.circleAt(loc[0], loc[1], size));
}
} else {
g.setColor(colors[NB_HISTORY-1]);
g.fill(GUIUtils.circleAt(getCenterX(), getCenterY(), sizeInPixels));
}
}
@Override
public Projectile getObject() {
return getProjectile();
}
public Projectile getProjectile() {
return projectile;
}
public synchronized void setSize(double sizeInPixels) {
this.sizeInPixels = Math.min(MAX_DISPLAY_SIZE,
Math.max(MIN_DISPLAY_SIZE, DISPLAY_SCALE * sizeInPixels));
}
@Override
public double getHeight(Graphics2D g) {
return sizeInPixels;
}
@Override
public double getWidth(Graphics2D g) {
return sizeInPixels;
}
@Override
public boolean isObjectAlive() {
return !getFacade().isTerminated(getProjectile());
}
@Override
public synchronized void update() {
setSize(getScreen().worldToScreenDistance(getFacade().getRadius(getProjectile())));
double[] loc = getFacade().getLocation(getProjectile());
setCenterLocation(getScreen().getScreenX(loc[0]), getScreen().getScreenY(loc[1]));
}
@Override
public synchronized void setCenterLocation(double x, double y) {
super.setCenterLocation(x, y);
if (moving && !lastLocations.isEmpty()) {
// do some averaving to show some intermediate positions for
// fast-moving object (rifle projectiles)
if (lastLocations.size() > 1) {
double[] c1 = lastLocations.get(lastLocations.size() - 1);
double[] c2 = lastLocations.get(0);
lastLocations.add(new double[] { (c1[0] + c2[0]) / 2,
(c1[1] + c2[1]) / 2 });
}
double[] prev = lastLocations.get(lastLocations.size() - 1);
lastLocations.remove(prev);
for (int i = 0; i < NB_HISTORY; i++) {
if (prev != null) {
double t = (double) i / (NB_HISTORY);
lastLocations.add(new double[] { t * x + (1 - t) * prev[0],
t * y + (1 - t) * prev[1] });
}
}
}
lastLocations.add(new double[] { x, y });
}
public synchronized void setDoneMoving() {
this.moving = false;
}
}

View File

View File

View File

View File

@@ -0,0 +1,443 @@
package worms.programs;
import java.util.ArrayList;
import java.util.List;
import worms.util.ModelException;
import worms.util.MustNotImplementException;
/**
* A program factory is used by the parser ({@link ProgramParser}) to construct
* an in-memory representation of your program. For example, when reading the
* program source code
*
* <pre>
* print 2.0
* </pre>
*
* the parser will create a Program object by (conceptually) executing the
* following code:
*
* <pre>
* factory.createProgram(Collections.emptyList(),
* factory.createPrintStatement(factory.createDoubleLiteral(2.0)));
* </pre>
*
* on the returned factory object.
*
* <p>
* For testing, you may use the methods from {@link ProgramParser} yourself.
* </p>
*
* <p>
* You should declare your class as follows:<code><pre>
* public class ProgramFactory implements IProgramFactory&lt;MyExpression, MyStatement, MyProc, Program&gt;
* </pre></code> where MyExpression, MyStatement, MyProc, and Program are your classes
* for representing expressions, statements, procedure definitions, and programs,
* respectively.
*
* <p>
* The SourceLocation object in the methods defined by this factory refers to
* the location (line and column) in the text file where the statement or
* expression begins.
*
* @param <E>
* Your class for representing an expression.
* @param <S>
* Your class for representing a statement.
* @param <P>
* Your class for representing a procedure.
* @param <Program>
* Your class for representing a program (should be Program).
*
*
*/
public interface IProgramFactory<E, S, P, Program> {
/* PROGRAM */
/**
* Create a program from the given arguments.
*
* @param procs
* The procedure definitions for the program.
* @param main
* The main statement of the program. Most likely this is a
* sequence statement.
* @return A new program.
*/
public Program createProgram(List<P> procs, S main) throws ModelException;
/**
* Create a program from the given argument.
*
* @param main
* The main statement of the program. Most likely this is a
* sequence statement.
* @return A new program without procedure definitions.
*/
public default Program createProgram(S main) throws ModelException {
return createProgram(new ArrayList<P>(), main);
}
/* PROCEDURE DEFINITIONS */
/**
* Create a procedure definition with the given name and body.
*
* @param procedureName
* The name of the procedure
* @param body
* The body of the procedure.
*/
public P createProcedureDefinition(String procedureName, S body, SourceLocation sourceLocation);
/* STATEMENTS */
/**
* Create a statement that assigns the value obtained by evaluating the
* given expression to a variable with the given name.
*/
public S createAssignmentStatement(String variableName, E value, SourceLocation sourceLocation)
throws ModelException;
/**
* Create a print statement that prints the value obtained by evaluating the
* given expression.
*/
public S createPrintStatement(E value, SourceLocation sourceLocation) throws ModelException;
/**
* Create a turn statement that makes the worm that is executing the program
* turn by the amount obtained by evaluating the given expression.
*/
public S createTurnStatement(E angle, SourceLocation location) throws ModelException;
/**
* Create a statement that makes the worm that is executing the program move
* one step.
*/
public S createMoveStatement(SourceLocation location) throws ModelException;
/**
* Returns a statement that makes the worm that is executing the program jump.
*/
public S createJumpStatement(SourceLocation location) throws ModelException;
/**
* Returns a statement that makes the worm that is executing the program eat.
*/
public S createEatStatement(SourceLocation location);
/**
* Returns a statement that makes the worm that is executing the program fire
* a weapon.
*/
public S createFireStatement(SourceLocation location) throws ModelException;
/**
* Create a sequence of statements involving the given list of statements.
*/
public S createSequenceStatement(List<S> statements, SourceLocation sourceLocation) throws ModelException;
/**
* Create an if-then-else statement involving the given condition and the
* given then-part and else-part.
* The else-part may be null.
*/
public S createIfStatement(E condition, S ifBody, S elseBody, SourceLocation sourceLocation) throws ModelException;
/**
* Create a while statement involving the given condition and given body.
*/
public S createWhileStatement(E condition, S body, SourceLocation sourceLocation) throws ModelException;
/**
* Create a break statement.
*/
public default S createBreakStatement(SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
// Individual students must not work out this method.
throw new MustNotImplementException();
}
/**
* Create an invoke statement that invokes the procedure with the given name.
*/
public default S createInvokeStatement(String procedureName, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
// Individual students must not work out this method.
throw new MustNotImplementException();
}
/* EXPRESSIONS */
/**
* Create an expression that evaluates to the current value of the given
* variable.
*/
public E createReadVariableExpression(String variableName, SourceLocation sourceLocation) throws ModelException;
/**
* Creates an expression that represents a literal double value.
*/
public E createDoubleLiteralExpression(double value, SourceLocation location) throws ModelException;
/**
* Creates an expression that represents a literal boolean value.
*/
public E createBooleanLiteralExpression(boolean value, SourceLocation location) throws ModelException;
/**
* Creates an expression that represents the null value.
*/
public E createNullExpression(SourceLocation location) throws ModelException;
/**
* Creates an expression that represents the self value, evaluating to the
* worm that executes the program.
*/
public E createSelfExpression(SourceLocation location) throws ModelException;
/**
* Returns an expression that evaluates to the addition of the values
* obtained by evaluating the given left and second expressions.
*/
public E createAdditionExpression(E left, E right, SourceLocation location) throws ModelException;
/**
* Returns an expression that evaluates to the subtraction of the values
* obtained by evaluating the first and second given expressions.
*/
public default E createSubtractionExpression(E left, E right, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the multiplication of the values
* obtained by evaluating the first and second given expressions.
*/
public default E createMultiplicationExpression(E left, E right, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the division of the values
* obtained by evaluating the first and second given expressions.
*/
public default E createDivisionExpression(E left, E right, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the square root of the value
* obtained by evaluating the given expression.
*/
public default E createSqrtExpression(E e, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the sine of the value
* obtained by evaluating the given expression.
*/
public default E createSinExpression(E e, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the cosine of the value
* obtained by evaluating the given expression.
*/
public default E createCosExpression(E e, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the conjunction of the values
* obtained by evaluating the given left and right expressions.
*/
public E createAndExpression(E left, E right, SourceLocation sourceLocation) throws ModelException;
/**
* Returns an expression that evaluates to the disjunction of the values
* obtained by evaluating the given left and right expressions.
*/
public default E createOrExpression(E left, E right, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to true when the given expression
* evaluates to false, and vice versa.
*/
public E createNotExpression(E expression, SourceLocation sourceLocation) throws ModelException;
/**
* Returns an expression that evaluates to true if the evaluation of the
* left expression yields a value that is equal to the value obtained by
* evaluating the right expression.
*/
public E createEqualityExpression(E left, E right, SourceLocation location) throws ModelException;
/**
* Returns an expression that evaluates to true if the evaluation of the
* left expression yields a value that is different from the value obtained by
* evaluating the right expression.
*/
public default E createInequalityExpression(E left, E right, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to true if the evaluation of the
* left expression yields a value that is less than the value obtained by
* evaluating the right expression.
*/
public E createLessThanExpression(E left, E right, SourceLocation location);
/**
* Returns an expression that evaluates to true if the evaluation of the
* left expression yields a value that is less than or equal to the value obtained by
* evaluating the right expression.
*/
public default E createLessThanOrEqualExpression(E left, E right, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to true if the evaluation of the
* left expression yields a value that is greater than the value obtained by
* evaluating the right expression.
*/
public default E createGreaterThanExpression(E left, E right, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to true if the evaluation of the
* left expression yields a value that is greater than or equal to the value obtained by
* evaluating the right expression.
*/
public default E createGreaterThanOrEqualExpression(E left, E right, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the position along the x-axis of
* the game object to which the given expression evaluates.
*/
public default E createGetXExpression(E e, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the position along the y-axis of
* the game object to which the given expression evaluates.
*/
public default E createGetYExpression(E e, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the radius of the game object to which
* the given expression evaluates.
*/
public default E createGetRadiusExpression(E e, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the direction of the game object to which
* the given expression evaluates.
*/
public default E createGetDirectionExpression(E entity, SourceLocation location)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the number of action points of the worm to which
* the given expression evaluates.
*/
public default E createGetActionPointsExpression(E entity, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the maximum number of action points of the worm to which
* the given expression evaluates.
*/
public default E createGetMaxActionPointsExpression(E entity, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the number of hit points of the game object to which
* the given expression evaluates.
*/
public default E createHitPointsExpression(E entity, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
public E createSearchObjectExpression(E angleDelta, SourceLocation sourceLocation) throws ModelException;
/**
* Returns an expression that evaluates to a boolean reflecting whether or not
* the executing worm belongs to the same team as the worm to which the given
* expression evaluates.
*/
public default E createSameTeamExpression(E entity, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
// Individual students must not work out this method.
throw new MustNotImplementException();
}
/**
* Returns an expression that evaluates to the distance between the executing worm
* and the game object to which the given expression evaluates.
*/
public E createDistanceExpression(E entity, SourceLocation sourceLocation) throws ModelException;
/**
* Returns a boolean indicating whether or not the object to which the given
* expression evaluates is a worm.
*/
public E createIsWormExpression(E entity, SourceLocation sourceLocation) throws ModelException;
/**
* Returns a boolean indicating whether or not the object to which the given
* expression evaluates is a portion of food.
*/
public default E createIsFoodExpression(E entity, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
/**
* Returns a boolean indicating whether or not the object to which the given
* expression evaluates is a projectile.
*/
public default E createIsProjectileExpression(E entity, SourceLocation sourceLocation)
throws ModelException, MustNotImplementException {
throw new MustNotImplementException();
}
}

View File

@@ -0,0 +1,20 @@
package worms.programs;
import java.util.List;
import worms.programs.SuccessOrFail.WrappedSuccessOrFail;
public class ParseOutcome<P> extends WrappedSuccessOrFail<P, List<String>> {
private ParseOutcome(SuccessOrFail<P, List<String>> outcome) {
super(outcome);
}
public static <P> ParseOutcome<P> success(P p) {
return new ParseOutcome<>(DefaultSuccessOrFail.success(p));
}
public static <P> ParseOutcome<P> failure(List<String> errors) {
return new ParseOutcome<>(DefaultSuccessOrFail.failure(errors));
}
}

View File

@@ -0,0 +1,245 @@
package worms.programs;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import worms.programs.IProgramFactory;
import worms.programs.internal.parser.ParserVisitor;
import worms.programs.internal.parser.generated.WormsProgramLexer;
import worms.programs.internal.parser.generated.WormsProgramParser;
import worms.internal.gui.GUIUtils;
import worms.model.Program;
/**
* Parser for Worms programs.
*
* To use this class, first create an implementation of {@link IProgramFactory}:
*
* <pre>
* <code>
* IProgramFactory&lt;MyExpression, MyStatement, MyProcedure, Program&gt; factory = new ProgramFactory();
* </code>
* </pre>
*
* The easiest way to use this class for parsing a Program given as a String is
* via the {@link #parseProgramFromString(String, IProgramFactory)} method:
*
* <pre>
* <code>
* Program program = ProgramParser.parseProgram(text, factory);
* </code>
* </pre>
*
* For more control, create an instance of this class:
*
* <pre>
* <code>
* ProgramParser&lt;MyExpression, MyStatement, Task&gt; parser = new ProgramParser<>(factory);
* </code>
* </pre>
*
* Finally, parse a string or file: <code><pre>
* ParseOurcome&lt;Program&gt; parseResult = parser.parse(textToParse);
* </pre></code>
*
* If parsing is successful, <code>parseResult.isSuccess()</code> returns true
* and <code>parseResult.getSuccessValue()</code> returns the created program.
*
* If parsing was not successful, <code>parseResult.ifSuccess()</code> returns
* false and <code>parseResult.getFailValue()</code> returns the list of errors
* during parsing.
*
*
* @param E
* The type of expressions
* @param S
* The type of statements
* @param P
* The type of procedures
* @param Prg
* The type of program that is created; should be your
* worms.model.Program class
*/
public class ProgramParser<E, S, P, Prg> {
private final IProgramFactory<E, S, P, Prg> factory;
private final List<String> errors = new ArrayList<>();
protected ProgramParser(IProgramFactory<E, S, P, Prg> factory) {
if (factory == null) {
throw new NullPointerException("Factory must be effective.");
}
this.factory = factory;
}
public IProgramFactory<E, S, P, Prg> getFactory() {
return factory;
}
/**
* Returns the program that results from parsing the given string, or
* Optional.empty() if parsing has failed.
*
* When parsing has failed, the error messages can be retrieved with the
* getErrors() method.
*
*/
public ParseOutcome<Prg> parseString(String string) {
return parse(CharStreams.fromString(string));
}
/**
* Returns the program that results from parsing the file with the given name,
* or Optional.empty() if parsing has failed.
*
* When parsing has failed, the error messages can be retrieved with the
* getErrors() method.
*/
public ParseOutcome<Prg> parseFile(String filename) throws IOException {
return parse(CharStreams.fromStream(GUIUtils.openResource(filename)));
}
/**
* Returns the program that results from parsing the file with the given URL, or
* Optional.empty() if parsing has failed.
*
* When parsing has failed, the error messages can be retrieved with the
* getErrors() method.
*/
public ParseOutcome<Prg> parseFile(URL url) throws IOException {
return parse(CharStreams.fromStream(GUIUtils.openResource(url)));
}
/**
* Returns the program that results from parsing the given CharStream, or
* Optional.empty() if parsing has failed.
*
* When parsing has failed, the error messages can be retrieved with the
* getErrors() method.
*
* @note For more convenient methods, see the
* {@link #parseProgramFromString(String, ITaskFactory, List)},
* {@link #parseProgramFromFile(String, ITaskFactory, List)},
* {@link #parseString(String, List)} and {@link #parseFile(String, List)}
* methods.
*/
protected ParseOutcome<Prg> parse(CharStream input) {
reset();
WormsProgramLexer lexer = new WormsProgramLexer(input);
WormsProgramParser parser = new WormsProgramParser(new CommonTokenStream(lexer));
parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
int charPositionInLine, String msg, RecognitionException e) {
errors.add(msg + " (" + line + ", " + charPositionInLine + ")");
}
});
ParserVisitor<E, S, P, Prg> visitor = new ParserVisitor<>(factory);
try {
visitor.visitProgram(parser.program());
if (errors.isEmpty()) {
assert visitor.getMain() != null;
Prg program = factory.createProgram(visitor.getProcedures(), visitor.getMain());
if (program != null) {
return ParseOutcome.success(program);
}
errors.add("Factory did not return a Program object");
}
} catch (Exception e) {
e.printStackTrace();
errors.add(e.toString());
}
return ParseOutcome.failure(errors);
}
protected void reset() {
this.errors.clear();
}
public List<String> getErrors() {
return Collections.unmodifiableList(errors);
}
/**
* Create a new parser from the given factory.
*
* @param factory
* @return
*/
public static <E, S, T, P> ProgramParser<E, S, T, P> create(IProgramFactory<E, S, T, P> factory) {
return new ProgramParser<>(factory);
}
/**
* Parse program text using the given factory.
*
* @param text
* The text to parse
* @param factory
* The factory to use
* @return The parsed program, if any, or null if an error occurred during
* parsing.
*/
public static Program parseProgramFromString(String text, IProgramFactory<?, ?, ?, ? extends Program> factory) {
ProgramParser<?, ?, ?, ? extends Program> parser = create(factory);
ParseOutcome<? extends Program> outcome = parser.parseString(text);
if (outcome.isFail()) {
System.out.println("Parsing failed: " + outcome.getFailValue());
return null;
}
return outcome.getSuccessValue();
}
/**
* Parse program from a file using the given factory.
*
* @param filename
* The filename from which to read the program text
* @param factory
* The factory to use
* @return The parsed program, if any, or null if an error occurred during
* parsing.
*/
public static Program parseProgramFromFile(String filename, IProgramFactory<?, ?, ?, ? extends Program> factory)
throws IOException {
ProgramParser<?, ?, ?, ? extends Program> parser = create(factory);
ParseOutcome<? extends Program> outcome = parser.parseFile(filename);
if (outcome.isFail()) {
System.out.println("Parsing failed: " + outcome.getFailValue());
return null;
}
return outcome.getSuccessValue();
}
/**
* Parse program from a file using the given factory.
*
* @param filename
* The filename from which to read the program text
* @param factory
* The factory to use
* @return The parsed program, if any, or null if an error occurred during
* parsing.
*/
public static Program parseProgramFromURL(URL url, IProgramFactory<?, ?, ?, Program> factory) throws IOException {
ProgramParser<?, ?, ?, Program> parser = create(factory);
ParseOutcome<Program> outcome = parser.parseFile(url);
if (outcome.isFail()) {
System.out.println("Parsing failed: " + outcome.getFailValue());
return null;
}
return outcome.getSuccessValue();
}
}

View File

@@ -0,0 +1,61 @@
package worms.programs;
import be.kuleuven.cs.som.annotate.Value;
/**
* A source location represents a position in a source file,
* denoted by the line and column (position in the line) of
* a certain character in the file.
*
* This class is a value class.
*/
@Value
public final class SourceLocation {
private final int line;
private final int column;
public SourceLocation(int line, int column) {
this.line = line;
this.column = column;
}
public int getLine() {
return line;
}
public int getColumn() {
return column;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + column;
result = prime * result + line;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SourceLocation other = (SourceLocation) obj;
if (column != other.column)
return false;
if (line != other.line)
return false;
return true;
}
@Override
public String toString() {
return String.format("@%d,%d", line, column);
}
}

View File

@@ -0,0 +1,100 @@
package worms.programs;
/**
* An interface that holds either a success value of type S or a failure value of type F.
*/
public interface SuccessOrFail<S, F> {
public boolean isSuccess();
public S getSuccessValue();
public F getFailValue();
public default boolean isFail() {
return !isSuccess();
}
public static class DefaultSuccessOrFail<S, F> implements SuccessOrFail<S, F> {
private final boolean success;
private final F failValue;
private final S successValue;
private DefaultSuccessOrFail(boolean success, S successValue, F failValue) {
if (success && failValue != null) {
throw new IllegalArgumentException();
}
if (!success && successValue != null) {
throw new IllegalArgumentException();
}
this.success = success;
this.successValue = successValue;
this.failValue = failValue;
}
@Override
public boolean isSuccess() {
return success;
}
@Override
public F getFailValue() {
return failValue;
}
@Override
public S getSuccessValue() {
return successValue;
}
public static <S, F> SuccessOrFail<S, F> success(S successValue) {
return new DefaultSuccessOrFail<>(true, successValue, null);
}
public static <S, F> SuccessOrFail<S, F> failure(F failValue) {
return new DefaultSuccessOrFail<>(false, null, failValue);
}
@Override
public String toString() {
if (isSuccess()) {
return "SUCCESS value: " + getSuccessValue();
} else {
return "FAIL value: " + getFailValue();
}
}
}
public static class WrappedSuccessOrFail<S, F> implements SuccessOrFail<S, F> {
private final SuccessOrFail<S, F> wrapped;
protected WrappedSuccessOrFail(SuccessOrFail<S, F> wrapped) {
if (wrapped == null) {
throw new NullPointerException();
}
this.wrapped = wrapped;
}
@Override
public boolean isSuccess() {
return wrapped.isSuccess();
}
@Override
public S getSuccessValue() {
return wrapped.getSuccessValue();
}
@Override
public F getFailValue() {
return wrapped.getFailValue();
}
@Override
public String toString() {
return wrapped.toString();
}
}
}

View File

@@ -0,0 +1,392 @@
package worms.programs.internal.parser;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import worms.programs.IProgramFactory;
import worms.programs.SourceLocation;
import worms.programs.internal.parser.generated.WormsProgramBaseVisitor;
import worms.programs.internal.parser.generated.WormsProgramLexer;
import worms.programs.internal.parser.generated.WormsProgramParser.AddSubExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.AndOrExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.AssignmentStatementContext;
import worms.programs.internal.parser.generated.WormsProgramParser.BreakStatementContext;
import worms.programs.internal.parser.generated.WormsProgramParser.ComparisonExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.ConstantExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.CosExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.DistanceExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.EatActionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.FalseLiteralExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.FireActionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.GetAPExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.GetDirectionExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.GetHPExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.GetMaxAPExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.GetRadiusExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.GetXExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.GetYExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.IfStatementContext;
import worms.programs.internal.parser.generated.WormsProgramParser.InvokeStatementContext;
import worms.programs.internal.parser.generated.WormsProgramParser.IsFoodExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.IsProjectileExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.IsWormExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.JumpActionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.MoveActionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.MulDivExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.NotExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.NullExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.ParenExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.PrintStatementContext;
import worms.programs.internal.parser.generated.WormsProgramParser.ProceduredefContext;
import worms.programs.internal.parser.generated.WormsProgramParser.ProgramContext;
import worms.programs.internal.parser.generated.WormsProgramParser.ReadVariableExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.SameTeamExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.SearchObjExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.SelfExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.SequenceStatementContext;
import worms.programs.internal.parser.generated.WormsProgramParser.SinExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.SqrtExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.TrueLiteralExpressionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.TurnActionContext;
import worms.programs.internal.parser.generated.WormsProgramParser.WhileStatementContext;
public class ParserVisitor<E, S, P, Prg> extends WormsProgramBaseVisitor<Void> {
@Override
public Void visitProgram(ProgramContext ctx) {
procedures = ctx.procdef.stream().map(procdef -> procDefVisitor.visit(procdef)).collect(Collectors.toList());
List<S> mainStmts = ctx.programBody.stream().map(stmt -> statementVisitor.visit(stmt))
.collect(Collectors.toList());
if (mainStmts.size() == 1) {
main = mainStmts.get(0);
} else {
main = factory.createSequenceStatement(mainStmts, toSourceLocation(ctx));
}
assert main != null;
return null;
}
private class ProcedureDefinitionVisitor extends WormsProgramBaseVisitor<P> {
@Override
public P visitProceduredef(ProceduredefContext ctx) {
return getFactory().createProcedureDefinition(ctx.procname.getText(), statementVisitor.visit(ctx.body),
toSourceLocation(ctx));
}
}
private class StatementVisitor extends WormsProgramBaseVisitor<S> {
@Override
public S visitAssignmentStatement(AssignmentStatementContext ctx) {
return getFactory().createAssignmentStatement(ctx.variableName.getText(),
expressionVisitor.visit(ctx.value), toSourceLocation(ctx));
}
@Override
public S visitWhileStatement(WhileStatementContext ctx) {
return getFactory().createWhileStatement(expressionVisitor.visit(ctx.condition),
statementVisitor.visit(ctx.body), toSourceLocation(ctx));
}
@Override
public S visitIfStatement(IfStatementContext ctx) {
S ifBody = statementVisitor.visit(ctx.ifbody);
S elseBody = null;
if (ctx.elsebody != null)
elseBody = statementVisitor.visit(ctx.elsebody);
return getFactory().createIfStatement(expressionVisitor.visit(ctx.condition), ifBody, elseBody,
toSourceLocation(ctx));
}
@Override
public S visitPrintStatement(PrintStatementContext ctx) {
return getFactory().createPrintStatement(expressionVisitor.visit(ctx.value), toSourceLocation(ctx));
}
@Override
public S visitSequenceStatement(SequenceStatementContext ctx) {
if (ctx.stmts.size() != 1) {
return getFactory().createSequenceStatement(
ctx.stmts.stream().map(this::visit).collect(Collectors.toList()), toSourceLocation(ctx));
} else {
return visit(ctx.stmts.get(0));
}
}
@Override
public S visitInvokeStatement(InvokeStatementContext ctx) {
return getFactory().createInvokeStatement(ctx.procName.getText(), toSourceLocation(ctx));
}
@Override
public S visitBreakStatement(BreakStatementContext ctx) {
return getFactory().createBreakStatement(toSourceLocation(ctx));
}
@Override
public S visitTurnAction(TurnActionContext ctx) {
return getFactory().createTurnStatement(expressionVisitor.visit(ctx.angle), toSourceLocation(ctx));
}
@Override
public S visitMoveAction(MoveActionContext ctx) {
return getFactory().createMoveStatement(toSourceLocation(ctx));
}
@Override
public S visitJumpAction(JumpActionContext ctx) {
return getFactory().createJumpStatement(toSourceLocation(ctx));
}
@Override
public S visitEatAction(EatActionContext ctx) {
return getFactory().createEatStatement(toSourceLocation(ctx));
}
@Override
public S visitFireAction(FireActionContext ctx) {
return getFactory().createFireStatement(toSourceLocation(ctx));
}
}
private class ExpressionVisitor extends WormsProgramBaseVisitor<E> {
@Override
public E visitReadVariableExpression(ReadVariableExpressionContext ctx) {
return getFactory().createReadVariableExpression(ctx.variable.getText(), toSourceLocation(ctx));
}
@Override
public E visitConstantExpression(ConstantExpressionContext ctx) {
return getFactory().createDoubleLiteralExpression(Double.parseDouble(ctx.value.getText()),
toSourceLocation(ctx));
}
@Override
public E visitTrueLiteralExpression(TrueLiteralExpressionContext ctx) {
return getFactory().createBooleanLiteralExpression(true, toSourceLocation(ctx));
}
@Override
public E visitFalseLiteralExpression(FalseLiteralExpressionContext ctx) {
return getFactory().createBooleanLiteralExpression(false, toSourceLocation(ctx));
}
@Override
public E visitNullExpression(NullExpressionContext ctx) {
return getFactory().createNullExpression(toSourceLocation(ctx));
}
@Override
public E visitSelfExpression(SelfExpressionContext ctx) {
return getFactory().createSelfExpression(toSourceLocation(ctx));
}
@Override
public E visitParenExpression(ParenExpressionContext ctx) {
return expressionVisitor.visit(ctx.subExpr);
}
@Override
public E visitAddSubExpression(AddSubExpressionContext ctx) {
switch (ctx.op.getType()) {
case WormsProgramLexer.ADD:
return getFactory().createAdditionExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.SUB:
return getFactory().createSubtractionExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
default:
throw new IllegalArgumentException("Unknown operator: " + ctx.op);
}
}
@Override
public E visitMulDivExpression(MulDivExpressionContext ctx) {
switch (ctx.op.getType()) {
case WormsProgramLexer.MUL:
return getFactory().createMultiplicationExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.DIV:
return getFactory().createDivisionExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
default:
throw new IllegalArgumentException("Unknown operator: " + ctx.op);
}
}
@Override
public E visitSqrtExpression(SqrtExpressionContext ctx) {
return getFactory().createSqrtExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitSinExpression(SinExpressionContext ctx) {
return getFactory().createSinExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitCosExpression(CosExpressionContext ctx) {
return getFactory().createCosExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitAndOrExpression(AndOrExpressionContext ctx) {
switch (ctx.op.getType()) {
case WormsProgramLexer.AND:
return getFactory().createAndExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.OR:
return getFactory().createOrExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
default:
throw new IllegalArgumentException("Unknown operator: " + ctx.op);
}
}
@Override
public E visitNotExpression(NotExpressionContext ctx) {
return getFactory().createNotExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitComparisonExpression(ComparisonExpressionContext ctx) {
switch (ctx.op.getType()) {
case WormsProgramLexer.LT:
return getFactory().createLessThanExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.LTE:
return getFactory().createLessThanOrEqualExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.GT:
return getFactory().createGreaterThanExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.GTE:
return getFactory().createGreaterThanOrEqualExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.EQ:
return getFactory().createEqualityExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
case WormsProgramLexer.NEQ:
return getFactory().createInequalityExpression(expressionVisitor.visit(ctx.left),
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
default:
throw new IllegalArgumentException("Unknown operand: " + ctx.op);
}
}
@Override
public E visitGetXExpression(GetXExpressionContext ctx) {
return getFactory().createGetXExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitGetYExpression(GetYExpressionContext ctx) {
return getFactory().createGetYExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitGetRadiusExpression(GetRadiusExpressionContext ctx) {
return getFactory().createGetRadiusExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitGetDirectionExpression(GetDirectionExpressionContext ctx) {
return getFactory().createGetDirectionExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitGetAPExpression(GetAPExpressionContext ctx) {
return getFactory().createGetActionPointsExpression(expressionVisitor.visit(ctx.expr),
toSourceLocation(ctx));
}
@Override
public E visitGetMaxAPExpression(GetMaxAPExpressionContext ctx) {
return getFactory().createGetMaxActionPointsExpression(expressionVisitor.visit(ctx.expr),
toSourceLocation(ctx));
}
@Override
public E visitGetHPExpression(GetHPExpressionContext ctx) {
return getFactory().createHitPointsExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitSameTeamExpression(SameTeamExpressionContext ctx) {
return getFactory().createSameTeamExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitSearchObjExpression(SearchObjExpressionContext ctx) {
return getFactory().createSearchObjectExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitDistanceExpression(DistanceExpressionContext ctx) {
return getFactory().createDistanceExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitIsWormExpression(IsWormExpressionContext ctx) {
return getFactory().createIsWormExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitIsFoodExpression(IsFoodExpressionContext ctx) {
return getFactory().createIsFoodExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
@Override
public E visitIsProjectileExpression(IsProjectileExpressionContext ctx) {
return getFactory().createIsProjectileExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
}
}
private final IProgramFactory<E, S, P, Prg> factory;
private final ProcedureDefinitionVisitor procDefVisitor = new ProcedureDefinitionVisitor();
private final StatementVisitor statementVisitor = new StatementVisitor();
private final ExpressionVisitor expressionVisitor = new ExpressionVisitor();
private S main;
private List<P> procedures;
public ParserVisitor(IProgramFactory<E, S, P, Prg> factory) {
if (factory == null) {
throw new NullPointerException();
}
this.factory = factory;
}
private SourceLocation toSourceLocation(ParserRuleContext ctx) {
int line = ctx.getStart().getLine();
int column = ctx.getStart().getCharPositionInLine();
return new SourceLocation(line, column);
}
public IProgramFactory<E, S, P, Prg> getFactory() {
return factory;
}
public int toInt(Token z) {
return Integer.parseInt(z.getText());
}
public S getMain() {
return main;
}
public List<P> getProcedures() {
return Collections.unmodifiableList(procedures);
}
}

View File

@@ -0,0 +1,200 @@
// ANTLR v4 Grammar for controling Worms.
// Check the tutorial at http://jnb.ociweb.com/jnb/jnbJun2008.html
// or http://www.antlr.org/ for details.
grammar WormsProgram;
@header {
package worms.programs.internal.parser.generated;
}
// ------------------------------------------------------------------------
// --- Eval and Related Definitions ---------------------------------------
// ------------------------------------------------------------------------
program: (procdef+=proceduredef)*
(programBody+=statement)*
;
proceduredef: DEF procname=IDENTIFIER COLON?
body=statement
;
statement: assignmentStatement
| whileStatement
| ifStatement
| printStatement
| sequenceStatement
| invokeStatement
| breakStatement
| actionStatement
;
assignmentStatement: variableName=IDENTIFIER ASSIGN value=expression ';'
;
whileStatement: WHILE condition=expression COLON?
body=statement
;
ifStatement: IF condition=expression COLON?
ifbody=statement
(ELSE COLON?
elsebody=statement)?
;
printStatement: PRINT value=expression ';'
;
sequenceStatement: LEFT_BRACE (stmts+=statement)* RIGHT_BRACE
;
invokeStatement: INVOKE procName=IDENTIFIER ';'
;
breakStatement: BREAK ';'
;
actionStatement: TURN angle=expression ';' #turnAction
| MOVE ';' #moveAction
| JUMP ';' #jumpAction
| EAT ';' #eatAction
| FIRE ';' #fireAction
;
// order here sets order of operations (important for left-recursive expressions!)
expression: variable=IDENTIFIER #readVariableExpression
| value=NUMBER #constantExpression
| TRUE #trueLiteralExpression
| FALSE #falseLiteralExpression
| NULL #nullExpression
| SELF #selfExpression
| LEFT_PAREN subExpr=expression RIGHT_PAREN #parenExpression
| left=expression op=(MUL | DIV) right=expression #mulDivExpression
| left=expression op=(ADD | SUB) right=expression #addSubExpression
| left=expression op=(LT | LTE | GT | GTE | EQ | NEQ) right=expression #comparisonExpression
| left=expression op=(AND | OR) right=expression #andOrExpression
| SQRT LEFT_PAREN expr=expression RIGHT_PAREN #sqrtExpression
| SIN LEFT_PAREN expr=expression RIGHT_PAREN #sinExpression
| COS LEFT_PAREN expr=expression RIGHT_PAREN #cosExpression
| NOT expr=expression #notExpression
| GETX expr=expression #getXExpression
| GETY expr=expression #getYExpression
| GETRADIUS expr=expression #getRadiusExpression
| GETDIR expr=expression #getDirectionExpression
| GETAP expr=expression #getAPExpression
| GETMAXAP expr=expression #getMaxAPExpression
| GETHP expr=expression #getHPExpression
| SAMETEAM expr=expression #sameTeamExpression
| SEARCHOBJ expr=expression #searchObjExpression
| DISTANCE expr=expression #distanceExpression
| ISWORM expr=expression #isWormExpression
| ISFOOD expr=expression #isFoodExpression
| ISPROJECTILE expr=expression #isProjectileExpression
;
// ------------------------------------------------------------------------
// --- Specifiers -----------------------------------------------
// ------------------------------------------------------------------------
NULL: 'null';
SELF: 'self';
TRUE: 'true';
FALSE: 'false';
// ------------------------------------------------------------------------
// --- Unary Operations ---------------------------------------------------
// ------------------------------------------------------------------------
SQRT: 'sqrt';
SIN: 'sin';
COS: 'cos';
NOT: '!';
GETX: 'getx';
GETY: 'gety';
GETRADIUS: 'getradius';
GETDIR: 'getdir';
GETAP: 'getap';
GETMAXAP: 'getmaxap';
GETHP: 'gethp';
SAMETEAM: 'sameteam';
SEARCHOBJ: 'searchobj';
DISTANCE: 'distance';
ISWORM: 'isworm';
ISFOOD: 'isfood';
ISPROJECTILE: 'isprojectile';
// ------------------------------------------------------------------------
// --- Actions -----------------------------------------------
// ------------------------------------------------------------------------
TURN: 'turn';
MOVE: 'move';
JUMP: 'jump';
EAT: 'eat';
FIRE: 'fire';
// ------------------------------------------------------------------------
// --- Control Flow -------------------------------------------------------
// ------------------------------------------------------------------------
DEF: 'def';
IF: 'if';
INVOKE: 'invoke';
THEN: 'then';
ELSE: 'else';
WHILE: 'while';
BREAK: 'break';
PRINT: 'print';
// ------------------------------------------------------------------------
// --- Assignment and Arithmetics -----------------------------------------
// ------------------------------------------------------------------------
ASSIGN: ':=';
ADD: '+';
SUB: '-';
MUL: '*';
DIV: '/';
AND: '&&';
OR: '||';
LT: '<';
LTE: '<=';
GT: '>';
GTE: '>=';
EQ: '==';
NEQ: '!=';
// ------------------------------------------------------------------------
// --- Literals and Variables ---------------------------------------------
// ------------------------------------------------------------------------
NUMBER: INTEGER | FLOAT;
FLOAT: INTEGER '.' ('0'..'9')+;
INTEGER: ('-'|'+')? ('0'..'9')+;
IDENTIFIER: LETTER (LETTER | DIGIT | '_')*;
fragment LETTER: LOWER | UPPER;
fragment LOWER: 'a'..'z';
fragment UPPER: 'A'..'Z';
fragment DIGIT: '0'..'9';
LEFT_PAREN: '(';
RIGHT_PAREN: ')';
LEFT_BRACE: '{';
RIGHT_BRACE: '}';
COLON: ':';
// ------------------------------------------------------------------------
// --- Syntactical Ballast ------------------------------------------------
// ------------------------------------------------------------------------
// Skip runs of newline, space and tab characters.
WHITESPACE: [ \t\r\n]+ -> skip;
// Single-line comments begin with //, are followed by any characters
// other than those in a newline, and are terminated by newline characters.
SINGLE_COMMENT: '//' ~('\r' | '\n')* NEWLINE -> skip;
fragment NEWLINE: ('\r'? '\n')+;

View File

@@ -0,0 +1,42 @@
package worms.programs.internal.parser.example;
import java.io.IOException;
import worms.programs.IProgramFactory;
import worms.programs.ParseOutcome;
import worms.programs.ProgramParser;
public class ExamplePrinter {
public static void main(String[] args) throws IOException {
IProgramFactory<PrintingObject, PrintingObject, PrintingObject, PrintingProgram> factory = PrintingObjectFactory.create();
ProgramParser<?, ?, ?, PrintingProgram> parser = ProgramParser.create(factory);
/*
ParseOutcome<PrintingProgram> outcome = parser.parseString(
"def controlled_move:"
+ " if getap self > 100.0:"
+ " { jump; print getx self; print gety self; }"
+ " else move;"
+ ""
+ "max_distance := 10.0;"
+ "while true: {"
+ " w := searchobj 0.0;"
+ " if isworm w: {"
+ " if sameteam w:"
+ " invoke controlled_move;"
+ " else if distance w < max_distance:"
+ " fire;"
+ " else"
+ " { turn d; max_distance := max_distance + 0.1; }"
+ " }"
+ "}");
*/
//ParseOutcome<PrintingProgram> outcome = parser.parseFile("programs/program_example.txt");
//ParseOutcome<PrintingProgram> outcome = parser.parseFile("programs/syntax_test.txt");
ParseOutcome<PrintingProgram> outcome = parser.parseFile("programs/program.txt");
System.out.println(outcome);
}
}

View File

@@ -0,0 +1,80 @@
package worms.programs.internal.parser.example;
import java.util.List;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
import worms.programs.SourceLocation;
public class PrintingObject {
private boolean indented = false;
private final StringBuilder repr = new StringBuilder();
public PrintingObject(SourceLocation loc, String method, Object... args) {
if (loc != null) {
method = loc + " " + method;
}
if (args.length > 1) {
indented(method + "(");
indented = true;
for (int i = 0; i < args.length; i++) {
indented(repr(args[i]), args.length > 1 && i < args.length - 1);
}
indented = false;
indented(")");
} else {
String msg = method + "( ";
if (args.length > 0) {
msg += repr(args[0]).toString().trim();
}
msg += " )";
indented(msg);
}
}
private String repr(Object object) {
if (object instanceof String) {
object = "\"" + object + "\"";
} else if (object instanceof List<?>) {
object = String.format("Arrays.toList(%s)", ((List<?>) object)
.stream().map(this::repr)
.collect(Collectors.joining(", ### Arrays.toList\n")));
}
if (object != null) {
return object.toString();
} else {
return "null";
}
}
@Override
public String toString() {
return repr.toString();
}
private void indented(Object object) {
indented(object, false);
}
private void indented(Object object, boolean appendComma) {
if (object != null) {
String str = object.toString();
StringTokenizer tok = new StringTokenizer(str, "\n");
while (tok.hasMoreTokens()) {
if (indented)
repr.append("| ");
repr.append(tok.nextToken());
if (!tok.hasMoreTokens() && appendComma) {
repr.append(",");
}
repr.append("\n");
}
} else {
if (indented)
repr.append(" null");
}
}
}

View File

@@ -0,0 +1,49 @@
package worms.programs.internal.parser.example;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import worms.programs.IProgramFactory;
import worms.programs.SourceLocation;
public class PrintingObjectFactory {
/**
* Creates an implementation of IProgramFactory where the implementation of
* each interface method (except createProgram) just creates a
* PrintingObject with all arguments.
*/
@SuppressWarnings("unchecked")
public static IProgramFactory<PrintingObject, PrintingObject, PrintingObject, PrintingProgram> create() {
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("createProgram")) {
List<PrintingObject> functions = (List<PrintingObject>)args[0];
PrintingObject main = (PrintingObject) args[1];
return new PrintingProgram(functions, main);
}
if (args != null) {
SourceLocation sourceLocation = (SourceLocation) args[args.length - 1];
if (args.length >= 1) {
return new PrintingObject(sourceLocation, method.getName(),
Arrays.copyOfRange(args, 0, args.length - 1));
} else {
return new PrintingObject(sourceLocation, method.getName());
}
} else {
return new PrintingObject(null, method.getName());
}
}
};
return (IProgramFactory<PrintingObject, PrintingObject, PrintingObject, PrintingProgram>) Proxy.newProxyInstance(
IProgramFactory.class.getClassLoader(), new Class[] { IProgramFactory.class }, handler);
}
}

View File

@@ -0,0 +1,22 @@
package worms.programs.internal.parser.example;
import java.util.List;
public class PrintingProgram {
private List<PrintingObject> procedures;
private PrintingObject main;
public PrintingProgram(List<PrintingObject> procedures, PrintingObject main) {
if (main == null) {
throw new NullPointerException("main null");
}
this.main = main;
this.procedures = procedures;
}
@Override
public String toString() {
return "Procedures: " + procedures.toString() + "\nMain:" + main.toString();
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,112 @@
T__0=1
NULL=2
SELF=3
TRUE=4
FALSE=5
SQRT=6
SIN=7
COS=8
NOT=9
GETX=10
GETY=11
GETRADIUS=12
GETDIR=13
GETAP=14
GETMAXAP=15
GETHP=16
SAMETEAM=17
SEARCHOBJ=18
DISTANCE=19
ISWORM=20
ISFOOD=21
ISPROJECTILE=22
TURN=23
MOVE=24
JUMP=25
EAT=26
FIRE=27
DEF=28
IF=29
INVOKE=30
THEN=31
ELSE=32
WHILE=33
BREAK=34
PRINT=35
ASSIGN=36
ADD=37
SUB=38
MUL=39
DIV=40
AND=41
OR=42
LT=43
LTE=44
GT=45
GTE=46
EQ=47
NEQ=48
NUMBER=49
FLOAT=50
INTEGER=51
IDENTIFIER=52
LEFT_PAREN=53
RIGHT_PAREN=54
LEFT_BRACE=55
RIGHT_BRACE=56
COLON=57
WHITESPACE=58
SINGLE_COMMENT=59
';'=1
'null'=2
'self'=3
'true'=4
'false'=5
'sqrt'=6
'sin'=7
'cos'=8
'!'=9
'getx'=10
'gety'=11
'getradius'=12
'getdir'=13
'getap'=14
'getmaxap'=15
'gethp'=16
'sameteam'=17
'searchobj'=18
'distance'=19
'isworm'=20
'isfood'=21
'isprojectile'=22
'turn'=23
'move'=24
'jump'=25
'eat'=26
'fire'=27
'def'=28
'if'=29
'invoke'=30
'then'=31
'else'=32
'while'=33
'break'=34
'print'=35
':='=36
'+'=37
'-'=38
'*'=39
'/'=40
'&&'=41
'||'=42
'<'=43
'<='=44
'>'=45
'>='=46
'=='=47
'!='=48
'('=53
')'=54
'{'=55
'}'=56
':'=57

View File

@@ -0,0 +1,317 @@
// Generated from WormsProgram.g4 by ANTLR 4.7.1
package worms.programs.internal.parser.generated;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
* This class provides an empty implementation of {@link WormsProgramVisitor},
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public class WormsProgramBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements WormsProgramVisitor<T> {
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitProgram(WormsProgramParser.ProgramContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitProceduredef(WormsProgramParser.ProceduredefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStatement(WormsProgramParser.StatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAssignmentStatement(WormsProgramParser.AssignmentStatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitWhileStatement(WormsProgramParser.WhileStatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIfStatement(WormsProgramParser.IfStatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitPrintStatement(WormsProgramParser.PrintStatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSequenceStatement(WormsProgramParser.SequenceStatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitInvokeStatement(WormsProgramParser.InvokeStatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitBreakStatement(WormsProgramParser.BreakStatementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitTurnAction(WormsProgramParser.TurnActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMoveAction(WormsProgramParser.MoveActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitJumpAction(WormsProgramParser.JumpActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitEatAction(WormsProgramParser.EatActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFireAction(WormsProgramParser.FireActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDistanceExpression(WormsProgramParser.DistanceExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitCosExpression(WormsProgramParser.CosExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGetYExpression(WormsProgramParser.GetYExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAndOrExpression(WormsProgramParser.AndOrExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIsWormExpression(WormsProgramParser.IsWormExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNotExpression(WormsProgramParser.NotExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitComparisonExpression(WormsProgramParser.ComparisonExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParenExpression(WormsProgramParser.ParenExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGetRadiusExpression(WormsProgramParser.GetRadiusExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitTrueLiteralExpression(WormsProgramParser.TrueLiteralExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNullExpression(WormsProgramParser.NullExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSqrtExpression(WormsProgramParser.SqrtExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSinExpression(WormsProgramParser.SinExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSameTeamExpression(WormsProgramParser.SameTeamExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIsProjectileExpression(WormsProgramParser.IsProjectileExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIsFoodExpression(WormsProgramParser.IsFoodExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConstantExpression(WormsProgramParser.ConstantExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSearchObjExpression(WormsProgramParser.SearchObjExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGetXExpression(WormsProgramParser.GetXExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitReadVariableExpression(WormsProgramParser.ReadVariableExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMulDivExpression(WormsProgramParser.MulDivExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGetDirectionExpression(WormsProgramParser.GetDirectionExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSelfExpression(WormsProgramParser.SelfExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGetHPExpression(WormsProgramParser.GetHPExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAddSubExpression(WormsProgramParser.AddSubExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGetMaxAPExpression(WormsProgramParser.GetMaxAPExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitGetAPExpression(WormsProgramParser.GetAPExpressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFalseLiteralExpression(WormsProgramParser.FalseLiteralExpressionContext ctx) { return visitChildren(ctx); }
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,280 @@
// Generated from WormsProgram.g4 by ANTLR 4.7.1
package worms.programs.internal.parser.generated;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class WormsProgramLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
T__0=1, NULL=2, SELF=3, TRUE=4, FALSE=5, SQRT=6, SIN=7, COS=8, NOT=9,
GETX=10, GETY=11, GETRADIUS=12, GETDIR=13, GETAP=14, GETMAXAP=15, GETHP=16,
SAMETEAM=17, SEARCHOBJ=18, DISTANCE=19, ISWORM=20, ISFOOD=21, ISPROJECTILE=22,
TURN=23, MOVE=24, JUMP=25, EAT=26, FIRE=27, DEF=28, IF=29, INVOKE=30,
THEN=31, ELSE=32, WHILE=33, BREAK=34, PRINT=35, ASSIGN=36, ADD=37, SUB=38,
MUL=39, DIV=40, AND=41, OR=42, LT=43, LTE=44, GT=45, GTE=46, EQ=47, NEQ=48,
NUMBER=49, FLOAT=50, INTEGER=51, IDENTIFIER=52, LEFT_PAREN=53, RIGHT_PAREN=54,
LEFT_BRACE=55, RIGHT_BRACE=56, COLON=57, WHITESPACE=58, SINGLE_COMMENT=59;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
"DEFAULT_MODE"
};
public static final String[] ruleNames = {
"T__0", "NULL", "SELF", "TRUE", "FALSE", "SQRT", "SIN", "COS", "NOT",
"GETX", "GETY", "GETRADIUS", "GETDIR", "GETAP", "GETMAXAP", "GETHP", "SAMETEAM",
"SEARCHOBJ", "DISTANCE", "ISWORM", "ISFOOD", "ISPROJECTILE", "TURN", "MOVE",
"JUMP", "EAT", "FIRE", "DEF", "IF", "INVOKE", "THEN", "ELSE", "WHILE",
"BREAK", "PRINT", "ASSIGN", "ADD", "SUB", "MUL", "DIV", "AND", "OR", "LT",
"LTE", "GT", "GTE", "EQ", "NEQ", "NUMBER", "FLOAT", "INTEGER", "IDENTIFIER",
"LETTER", "LOWER", "UPPER", "DIGIT", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACE",
"RIGHT_BRACE", "COLON", "WHITESPACE", "SINGLE_COMMENT", "NEWLINE"
};
private static final String[] _LITERAL_NAMES = {
null, "';'", "'null'", "'self'", "'true'", "'false'", "'sqrt'", "'sin'",
"'cos'", "'!'", "'getx'", "'gety'", "'getradius'", "'getdir'", "'getap'",
"'getmaxap'", "'gethp'", "'sameteam'", "'searchobj'", "'distance'", "'isworm'",
"'isfood'", "'isprojectile'", "'turn'", "'move'", "'jump'", "'eat'", "'fire'",
"'def'", "'if'", "'invoke'", "'then'", "'else'", "'while'", "'break'",
"'print'", "':='", "'+'", "'-'", "'*'", "'/'", "'&&'", "'||'", "'<'",
"'<='", "'>'", "'>='", "'=='", "'!='", null, null, null, null, "'('",
"')'", "'{'", "'}'", "':'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, "NULL", "SELF", "TRUE", "FALSE", "SQRT", "SIN", "COS", "NOT",
"GETX", "GETY", "GETRADIUS", "GETDIR", "GETAP", "GETMAXAP", "GETHP", "SAMETEAM",
"SEARCHOBJ", "DISTANCE", "ISWORM", "ISFOOD", "ISPROJECTILE", "TURN", "MOVE",
"JUMP", "EAT", "FIRE", "DEF", "IF", "INVOKE", "THEN", "ELSE", "WHILE",
"BREAK", "PRINT", "ASSIGN", "ADD", "SUB", "MUL", "DIV", "AND", "OR", "LT",
"LTE", "GT", "GTE", "EQ", "NEQ", "NUMBER", "FLOAT", "INTEGER", "IDENTIFIER",
"LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACE", "RIGHT_BRACE", "COLON", "WHITESPACE",
"SINGLE_COMMENT"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public WormsProgramLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "WormsProgram.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getChannelNames() { return channelNames; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2=\u01bf\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
"\4>\t>\4?\t?\4@\t@\4A\tA\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3"+
"\4\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\b"+
"\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\f\3\f"+
"\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3"+
"\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3"+
"\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3"+
"\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3"+
"\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3"+
"\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3"+
"\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3"+
"\30\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3"+
"\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3"+
"\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3\"\3\"\3\""+
"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3%\3%\3%\3&\3&\3\'\3"+
"\'\3(\3(\3)\3)\3*\3*\3*\3+\3+\3+\3,\3,\3-\3-\3-\3.\3.\3/\3/\3/\3\60\3"+
"\60\3\60\3\61\3\61\3\61\3\62\3\62\5\62\u0176\n\62\3\63\3\63\3\63\6\63"+
"\u017b\n\63\r\63\16\63\u017c\3\64\5\64\u0180\n\64\3\64\6\64\u0183\n\64"+
"\r\64\16\64\u0184\3\65\3\65\3\65\3\65\7\65\u018b\n\65\f\65\16\65\u018e"+
"\13\65\3\66\3\66\5\66\u0192\n\66\3\67\3\67\38\38\39\39\3:\3:\3;\3;\3<"+
"\3<\3=\3=\3>\3>\3?\6?\u01a5\n?\r?\16?\u01a6\3?\3?\3@\3@\3@\3@\7@\u01af"+
"\n@\f@\16@\u01b2\13@\3@\3@\3@\3@\3A\5A\u01b9\nA\3A\6A\u01bc\nA\rA\16A"+
"\u01bd\2\2B\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33"+
"\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67"+
"\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65"+
"i\66k\2m\2o\2q\2s\67u8w9y:{;}<\177=\u0081\2\3\2\5\4\2--//\5\2\13\f\17"+
"\17\"\"\4\2\f\f\17\17\2\u01c5\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t"+
"\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2"+
"\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2"+
"\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2"+
"+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2"+
"\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2"+
"C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3"+
"\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2"+
"\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2"+
"i\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3"+
"\2\2\2\2\177\3\2\2\2\3\u0083\3\2\2\2\5\u0085\3\2\2\2\7\u008a\3\2\2\2\t"+
"\u008f\3\2\2\2\13\u0094\3\2\2\2\r\u009a\3\2\2\2\17\u009f\3\2\2\2\21\u00a3"+
"\3\2\2\2\23\u00a7\3\2\2\2\25\u00a9\3\2\2\2\27\u00ae\3\2\2\2\31\u00b3\3"+
"\2\2\2\33\u00bd\3\2\2\2\35\u00c4\3\2\2\2\37\u00ca\3\2\2\2!\u00d3\3\2\2"+
"\2#\u00d9\3\2\2\2%\u00e2\3\2\2\2\'\u00ec\3\2\2\2)\u00f5\3\2\2\2+\u00fc"+
"\3\2\2\2-\u0103\3\2\2\2/\u0110\3\2\2\2\61\u0115\3\2\2\2\63\u011a\3\2\2"+
"\2\65\u011f\3\2\2\2\67\u0123\3\2\2\29\u0128\3\2\2\2;\u012c\3\2\2\2=\u012f"+
"\3\2\2\2?\u0136\3\2\2\2A\u013b\3\2\2\2C\u0140\3\2\2\2E\u0146\3\2\2\2G"+
"\u014c\3\2\2\2I\u0152\3\2\2\2K\u0155\3\2\2\2M\u0157\3\2\2\2O\u0159\3\2"+
"\2\2Q\u015b\3\2\2\2S\u015d\3\2\2\2U\u0160\3\2\2\2W\u0163\3\2\2\2Y\u0165"+
"\3\2\2\2[\u0168\3\2\2\2]\u016a\3\2\2\2_\u016d\3\2\2\2a\u0170\3\2\2\2c"+
"\u0175\3\2\2\2e\u0177\3\2\2\2g\u017f\3\2\2\2i\u0186\3\2\2\2k\u0191\3\2"+
"\2\2m\u0193\3\2\2\2o\u0195\3\2\2\2q\u0197\3\2\2\2s\u0199\3\2\2\2u\u019b"+
"\3\2\2\2w\u019d\3\2\2\2y\u019f\3\2\2\2{\u01a1\3\2\2\2}\u01a4\3\2\2\2\177"+
"\u01aa\3\2\2\2\u0081\u01bb\3\2\2\2\u0083\u0084\7=\2\2\u0084\4\3\2\2\2"+
"\u0085\u0086\7p\2\2\u0086\u0087\7w\2\2\u0087\u0088\7n\2\2\u0088\u0089"+
"\7n\2\2\u0089\6\3\2\2\2\u008a\u008b\7u\2\2\u008b\u008c\7g\2\2\u008c\u008d"+
"\7n\2\2\u008d\u008e\7h\2\2\u008e\b\3\2\2\2\u008f\u0090\7v\2\2\u0090\u0091"+
"\7t\2\2\u0091\u0092\7w\2\2\u0092\u0093\7g\2\2\u0093\n\3\2\2\2\u0094\u0095"+
"\7h\2\2\u0095\u0096\7c\2\2\u0096\u0097\7n\2\2\u0097\u0098\7u\2\2\u0098"+
"\u0099\7g\2\2\u0099\f\3\2\2\2\u009a\u009b\7u\2\2\u009b\u009c\7s\2\2\u009c"+
"\u009d\7t\2\2\u009d\u009e\7v\2\2\u009e\16\3\2\2\2\u009f\u00a0\7u\2\2\u00a0"+
"\u00a1\7k\2\2\u00a1\u00a2\7p\2\2\u00a2\20\3\2\2\2\u00a3\u00a4\7e\2\2\u00a4"+
"\u00a5\7q\2\2\u00a5\u00a6\7u\2\2\u00a6\22\3\2\2\2\u00a7\u00a8\7#\2\2\u00a8"+
"\24\3\2\2\2\u00a9\u00aa\7i\2\2\u00aa\u00ab\7g\2\2\u00ab\u00ac\7v\2\2\u00ac"+
"\u00ad\7z\2\2\u00ad\26\3\2\2\2\u00ae\u00af\7i\2\2\u00af\u00b0\7g\2\2\u00b0"+
"\u00b1\7v\2\2\u00b1\u00b2\7{\2\2\u00b2\30\3\2\2\2\u00b3\u00b4\7i\2\2\u00b4"+
"\u00b5\7g\2\2\u00b5\u00b6\7v\2\2\u00b6\u00b7\7t\2\2\u00b7\u00b8\7c\2\2"+
"\u00b8\u00b9\7f\2\2\u00b9\u00ba\7k\2\2\u00ba\u00bb\7w\2\2\u00bb\u00bc"+
"\7u\2\2\u00bc\32\3\2\2\2\u00bd\u00be\7i\2\2\u00be\u00bf\7g\2\2\u00bf\u00c0"+
"\7v\2\2\u00c0\u00c1\7f\2\2\u00c1\u00c2\7k\2\2\u00c2\u00c3\7t\2\2\u00c3"+
"\34\3\2\2\2\u00c4\u00c5\7i\2\2\u00c5\u00c6\7g\2\2\u00c6\u00c7\7v\2\2\u00c7"+
"\u00c8\7c\2\2\u00c8\u00c9\7r\2\2\u00c9\36\3\2\2\2\u00ca\u00cb\7i\2\2\u00cb"+
"\u00cc\7g\2\2\u00cc\u00cd\7v\2\2\u00cd\u00ce\7o\2\2\u00ce\u00cf\7c\2\2"+
"\u00cf\u00d0\7z\2\2\u00d0\u00d1\7c\2\2\u00d1\u00d2\7r\2\2\u00d2 \3\2\2"+
"\2\u00d3\u00d4\7i\2\2\u00d4\u00d5\7g\2\2\u00d5\u00d6\7v\2\2\u00d6\u00d7"+
"\7j\2\2\u00d7\u00d8\7r\2\2\u00d8\"\3\2\2\2\u00d9\u00da\7u\2\2\u00da\u00db"+
"\7c\2\2\u00db\u00dc\7o\2\2\u00dc\u00dd\7g\2\2\u00dd\u00de\7v\2\2\u00de"+
"\u00df\7g\2\2\u00df\u00e0\7c\2\2\u00e0\u00e1\7o\2\2\u00e1$\3\2\2\2\u00e2"+
"\u00e3\7u\2\2\u00e3\u00e4\7g\2\2\u00e4\u00e5\7c\2\2\u00e5\u00e6\7t\2\2"+
"\u00e6\u00e7\7e\2\2\u00e7\u00e8\7j\2\2\u00e8\u00e9\7q\2\2\u00e9\u00ea"+
"\7d\2\2\u00ea\u00eb\7l\2\2\u00eb&\3\2\2\2\u00ec\u00ed\7f\2\2\u00ed\u00ee"+
"\7k\2\2\u00ee\u00ef\7u\2\2\u00ef\u00f0\7v\2\2\u00f0\u00f1\7c\2\2\u00f1"+
"\u00f2\7p\2\2\u00f2\u00f3\7e\2\2\u00f3\u00f4\7g\2\2\u00f4(\3\2\2\2\u00f5"+
"\u00f6\7k\2\2\u00f6\u00f7\7u\2\2\u00f7\u00f8\7y\2\2\u00f8\u00f9\7q\2\2"+
"\u00f9\u00fa\7t\2\2\u00fa\u00fb\7o\2\2\u00fb*\3\2\2\2\u00fc\u00fd\7k\2"+
"\2\u00fd\u00fe\7u\2\2\u00fe\u00ff\7h\2\2\u00ff\u0100\7q\2\2\u0100\u0101"+
"\7q\2\2\u0101\u0102\7f\2\2\u0102,\3\2\2\2\u0103\u0104\7k\2\2\u0104\u0105"+
"\7u\2\2\u0105\u0106\7r\2\2\u0106\u0107\7t\2\2\u0107\u0108\7q\2\2\u0108"+
"\u0109\7l\2\2\u0109\u010a\7g\2\2\u010a\u010b\7e\2\2\u010b\u010c\7v\2\2"+
"\u010c\u010d\7k\2\2\u010d\u010e\7n\2\2\u010e\u010f\7g\2\2\u010f.\3\2\2"+
"\2\u0110\u0111\7v\2\2\u0111\u0112\7w\2\2\u0112\u0113\7t\2\2\u0113\u0114"+
"\7p\2\2\u0114\60\3\2\2\2\u0115\u0116\7o\2\2\u0116\u0117\7q\2\2\u0117\u0118"+
"\7x\2\2\u0118\u0119\7g\2\2\u0119\62\3\2\2\2\u011a\u011b\7l\2\2\u011b\u011c"+
"\7w\2\2\u011c\u011d\7o\2\2\u011d\u011e\7r\2\2\u011e\64\3\2\2\2\u011f\u0120"+
"\7g\2\2\u0120\u0121\7c\2\2\u0121\u0122\7v\2\2\u0122\66\3\2\2\2\u0123\u0124"+
"\7h\2\2\u0124\u0125\7k\2\2\u0125\u0126\7t\2\2\u0126\u0127\7g\2\2\u0127"+
"8\3\2\2\2\u0128\u0129\7f\2\2\u0129\u012a\7g\2\2\u012a\u012b\7h\2\2\u012b"+
":\3\2\2\2\u012c\u012d\7k\2\2\u012d\u012e\7h\2\2\u012e<\3\2\2\2\u012f\u0130"+
"\7k\2\2\u0130\u0131\7p\2\2\u0131\u0132\7x\2\2\u0132\u0133\7q\2\2\u0133"+
"\u0134\7m\2\2\u0134\u0135\7g\2\2\u0135>\3\2\2\2\u0136\u0137\7v\2\2\u0137"+
"\u0138\7j\2\2\u0138\u0139\7g\2\2\u0139\u013a\7p\2\2\u013a@\3\2\2\2\u013b"+
"\u013c\7g\2\2\u013c\u013d\7n\2\2\u013d\u013e\7u\2\2\u013e\u013f\7g\2\2"+
"\u013fB\3\2\2\2\u0140\u0141\7y\2\2\u0141\u0142\7j\2\2\u0142\u0143\7k\2"+
"\2\u0143\u0144\7n\2\2\u0144\u0145\7g\2\2\u0145D\3\2\2\2\u0146\u0147\7"+
"d\2\2\u0147\u0148\7t\2\2\u0148\u0149\7g\2\2\u0149\u014a\7c\2\2\u014a\u014b"+
"\7m\2\2\u014bF\3\2\2\2\u014c\u014d\7r\2\2\u014d\u014e\7t\2\2\u014e\u014f"+
"\7k\2\2\u014f\u0150\7p\2\2\u0150\u0151\7v\2\2\u0151H\3\2\2\2\u0152\u0153"+
"\7<\2\2\u0153\u0154\7?\2\2\u0154J\3\2\2\2\u0155\u0156\7-\2\2\u0156L\3"+
"\2\2\2\u0157\u0158\7/\2\2\u0158N\3\2\2\2\u0159\u015a\7,\2\2\u015aP\3\2"+
"\2\2\u015b\u015c\7\61\2\2\u015cR\3\2\2\2\u015d\u015e\7(\2\2\u015e\u015f"+
"\7(\2\2\u015fT\3\2\2\2\u0160\u0161\7~\2\2\u0161\u0162\7~\2\2\u0162V\3"+
"\2\2\2\u0163\u0164\7>\2\2\u0164X\3\2\2\2\u0165\u0166\7>\2\2\u0166\u0167"+
"\7?\2\2\u0167Z\3\2\2\2\u0168\u0169\7@\2\2\u0169\\\3\2\2\2\u016a\u016b"+
"\7@\2\2\u016b\u016c\7?\2\2\u016c^\3\2\2\2\u016d\u016e\7?\2\2\u016e\u016f"+
"\7?\2\2\u016f`\3\2\2\2\u0170\u0171\7#\2\2\u0171\u0172\7?\2\2\u0172b\3"+
"\2\2\2\u0173\u0176\5g\64\2\u0174\u0176\5e\63\2\u0175\u0173\3\2\2\2\u0175"+
"\u0174\3\2\2\2\u0176d\3\2\2\2\u0177\u0178\5g\64\2\u0178\u017a\7\60\2\2"+
"\u0179\u017b\4\62;\2\u017a\u0179\3\2\2\2\u017b\u017c\3\2\2\2\u017c\u017a"+
"\3\2\2\2\u017c\u017d\3\2\2\2\u017df\3\2\2\2\u017e\u0180\t\2\2\2\u017f"+
"\u017e\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0182\3\2\2\2\u0181\u0183\4\62"+
";\2\u0182\u0181\3\2\2\2\u0183\u0184\3\2\2\2\u0184\u0182\3\2\2\2\u0184"+
"\u0185\3\2\2\2\u0185h\3\2\2\2\u0186\u018c\5k\66\2\u0187\u018b\5k\66\2"+
"\u0188\u018b\5q9\2\u0189\u018b\7a\2\2\u018a\u0187\3\2\2\2\u018a\u0188"+
"\3\2\2\2\u018a\u0189\3\2\2\2\u018b\u018e\3\2\2\2\u018c\u018a\3\2\2\2\u018c"+
"\u018d\3\2\2\2\u018dj\3\2\2\2\u018e\u018c\3\2\2\2\u018f\u0192\5m\67\2"+
"\u0190\u0192\5o8\2\u0191\u018f\3\2\2\2\u0191\u0190\3\2\2\2\u0192l\3\2"+
"\2\2\u0193\u0194\4c|\2\u0194n\3\2\2\2\u0195\u0196\4C\\\2\u0196p\3\2\2"+
"\2\u0197\u0198\4\62;\2\u0198r\3\2\2\2\u0199\u019a\7*\2\2\u019at\3\2\2"+
"\2\u019b\u019c\7+\2\2\u019cv\3\2\2\2\u019d\u019e\7}\2\2\u019ex\3\2\2\2"+
"\u019f\u01a0\7\177\2\2\u01a0z\3\2\2\2\u01a1\u01a2\7<\2\2\u01a2|\3\2\2"+
"\2\u01a3\u01a5\t\3\2\2\u01a4\u01a3\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a4"+
"\3\2\2\2\u01a6\u01a7\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01a9\b?\2\2\u01a9"+
"~\3\2\2\2\u01aa\u01ab\7\61\2\2\u01ab\u01ac\7\61\2\2\u01ac\u01b0\3\2\2"+
"\2\u01ad\u01af\n\4\2\2\u01ae\u01ad\3\2\2\2\u01af\u01b2\3\2\2\2\u01b0\u01ae"+
"\3\2\2\2\u01b0\u01b1\3\2\2\2\u01b1\u01b3\3\2\2\2\u01b2\u01b0\3\2\2\2\u01b3"+
"\u01b4\5\u0081A\2\u01b4\u01b5\3\2\2\2\u01b5\u01b6\b@\2\2\u01b6\u0080\3"+
"\2\2\2\u01b7\u01b9\7\17\2\2\u01b8\u01b7\3\2\2\2\u01b8\u01b9\3\2\2\2\u01b9"+
"\u01ba\3\2\2\2\u01ba\u01bc\7\f\2\2\u01bb\u01b8\3\2\2\2\u01bc\u01bd\3\2"+
"\2\2\u01bd\u01bb\3\2\2\2\u01bd\u01be\3\2\2\2\u01be\u0082\3\2\2\2\16\2"+
"\u0175\u017c\u017f\u0184\u018a\u018c\u0191\u01a6\u01b0\u01b8\u01bd\3\b"+
"\2\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

View File

@@ -0,0 +1,112 @@
T__0=1
NULL=2
SELF=3
TRUE=4
FALSE=5
SQRT=6
SIN=7
COS=8
NOT=9
GETX=10
GETY=11
GETRADIUS=12
GETDIR=13
GETAP=14
GETMAXAP=15
GETHP=16
SAMETEAM=17
SEARCHOBJ=18
DISTANCE=19
ISWORM=20
ISFOOD=21
ISPROJECTILE=22
TURN=23
MOVE=24
JUMP=25
EAT=26
FIRE=27
DEF=28
IF=29
INVOKE=30
THEN=31
ELSE=32
WHILE=33
BREAK=34
PRINT=35
ASSIGN=36
ADD=37
SUB=38
MUL=39
DIV=40
AND=41
OR=42
LT=43
LTE=44
GT=45
GTE=46
EQ=47
NEQ=48
NUMBER=49
FLOAT=50
INTEGER=51
IDENTIFIER=52
LEFT_PAREN=53
RIGHT_PAREN=54
LEFT_BRACE=55
RIGHT_BRACE=56
COLON=57
WHITESPACE=58
SINGLE_COMMENT=59
';'=1
'null'=2
'self'=3
'true'=4
'false'=5
'sqrt'=6
'sin'=7
'cos'=8
'!'=9
'getx'=10
'gety'=11
'getradius'=12
'getdir'=13
'getap'=14
'getmaxap'=15
'gethp'=16
'sameteam'=17
'searchobj'=18
'distance'=19
'isworm'=20
'isfood'=21
'isprojectile'=22
'turn'=23
'move'=24
'jump'=25
'eat'=26
'fire'=27
'def'=28
'if'=29
'invoke'=30
'then'=31
'else'=32
'while'=33
'break'=34
'print'=35
':='=36
'+'=37
'-'=38
'*'=39
'/'=40
'&&'=41
'||'=42
'<'=43
'<='=44
'>'=45
'>='=46
'=='=47
'!='=48
'('=53
')'=54
'{'=55
'}'=56
':'=57

View File

@@ -0,0 +1,306 @@
// Generated from WormsProgram.g4 by ANTLR 4.7.1
package worms.programs.internal.parser.generated;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link WormsProgramParser}.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public interface WormsProgramVisitor<T> extends ParseTreeVisitor<T> {
/**
* Visit a parse tree produced by {@link WormsProgramParser#program}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitProgram(WormsProgramParser.ProgramContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#proceduredef}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitProceduredef(WormsProgramParser.ProceduredefContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#statement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStatement(WormsProgramParser.StatementContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#assignmentStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAssignmentStatement(WormsProgramParser.AssignmentStatementContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#whileStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitWhileStatement(WormsProgramParser.WhileStatementContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#ifStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIfStatement(WormsProgramParser.IfStatementContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#printStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitPrintStatement(WormsProgramParser.PrintStatementContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#sequenceStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSequenceStatement(WormsProgramParser.SequenceStatementContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#invokeStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitInvokeStatement(WormsProgramParser.InvokeStatementContext ctx);
/**
* Visit a parse tree produced by {@link WormsProgramParser#breakStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitBreakStatement(WormsProgramParser.BreakStatementContext ctx);
/**
* Visit a parse tree produced by the {@code turnAction}
* labeled alternative in {@link WormsProgramParser#actionStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitTurnAction(WormsProgramParser.TurnActionContext ctx);
/**
* Visit a parse tree produced by the {@code moveAction}
* labeled alternative in {@link WormsProgramParser#actionStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitMoveAction(WormsProgramParser.MoveActionContext ctx);
/**
* Visit a parse tree produced by the {@code jumpAction}
* labeled alternative in {@link WormsProgramParser#actionStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitJumpAction(WormsProgramParser.JumpActionContext ctx);
/**
* Visit a parse tree produced by the {@code eatAction}
* labeled alternative in {@link WormsProgramParser#actionStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitEatAction(WormsProgramParser.EatActionContext ctx);
/**
* Visit a parse tree produced by the {@code fireAction}
* labeled alternative in {@link WormsProgramParser#actionStatement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFireAction(WormsProgramParser.FireActionContext ctx);
/**
* Visit a parse tree produced by the {@code distanceExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDistanceExpression(WormsProgramParser.DistanceExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code cosExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitCosExpression(WormsProgramParser.CosExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code getYExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGetYExpression(WormsProgramParser.GetYExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code andOrExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAndOrExpression(WormsProgramParser.AndOrExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code isWormExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIsWormExpression(WormsProgramParser.IsWormExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code notExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNotExpression(WormsProgramParser.NotExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code comparisonExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitComparisonExpression(WormsProgramParser.ComparisonExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code parenExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParenExpression(WormsProgramParser.ParenExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code getRadiusExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGetRadiusExpression(WormsProgramParser.GetRadiusExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code trueLiteralExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitTrueLiteralExpression(WormsProgramParser.TrueLiteralExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code nullExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNullExpression(WormsProgramParser.NullExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code sqrtExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSqrtExpression(WormsProgramParser.SqrtExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code sinExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSinExpression(WormsProgramParser.SinExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code sameTeamExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSameTeamExpression(WormsProgramParser.SameTeamExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code isProjectileExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIsProjectileExpression(WormsProgramParser.IsProjectileExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code isFoodExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIsFoodExpression(WormsProgramParser.IsFoodExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code constantExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConstantExpression(WormsProgramParser.ConstantExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code searchObjExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSearchObjExpression(WormsProgramParser.SearchObjExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code getXExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGetXExpression(WormsProgramParser.GetXExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code readVariableExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitReadVariableExpression(WormsProgramParser.ReadVariableExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code mulDivExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitMulDivExpression(WormsProgramParser.MulDivExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code getDirectionExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGetDirectionExpression(WormsProgramParser.GetDirectionExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code selfExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSelfExpression(WormsProgramParser.SelfExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code getHPExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGetHPExpression(WormsProgramParser.GetHPExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code addSubExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAddSubExpression(WormsProgramParser.AddSubExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code getMaxAPExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGetMaxAPExpression(WormsProgramParser.GetMaxAPExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code getAPExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitGetAPExpression(WormsProgramParser.GetAPExpressionContext ctx);
/**
* Visit a parse tree produced by the {@code falseLiteralExpression}
* labeled alternative in {@link WormsProgramParser#expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFalseLiteralExpression(WormsProgramParser.FalseLiteralExpressionContext ctx);
}

View File

View File