Initial commit
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Single and multiple assignments.
|
||||
*/
|
||||
public class AssignStmt extends Stmt {
|
||||
/**
|
||||
* List of left-hand sides.
|
||||
*/
|
||||
public final List<Expr> targets;
|
||||
/**
|
||||
* Right-hand-side value to be assigned.
|
||||
*/
|
||||
public final Expr value;
|
||||
|
||||
/**
|
||||
* AST for TARGETS[0] = TARGETS[1] = ... = VALUE spanning source locations
|
||||
* [LEFT..RIGHT].
|
||||
*/
|
||||
public AssignStmt(Location left, Location right,
|
||||
List<Expr> targets, Expr value) {
|
||||
super(left, right);
|
||||
this.targets = targets;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* <operand> <operator> <operand>.
|
||||
*/
|
||||
public class BinaryExpr extends Expr {
|
||||
|
||||
/**
|
||||
* Left operand.
|
||||
*/
|
||||
public final Expr left;
|
||||
/**
|
||||
* Operator name.
|
||||
*/
|
||||
public final String operator;
|
||||
/**
|
||||
* Right operand.
|
||||
*/
|
||||
public final Expr right;
|
||||
|
||||
/**
|
||||
* An AST for expressions of the form LEFTEXPR OP RIGHTEXPR
|
||||
* from text in range [LEFTLOC..RIGHTLOC].
|
||||
*/
|
||||
public BinaryExpr(Location leftLoc, Location rightLoc, Expr leftExpr,
|
||||
String op, Expr rightExpr) {
|
||||
super(leftLoc, rightLoc);
|
||||
left = leftExpr;
|
||||
operator = op;
|
||||
right = rightExpr;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Literals True or False.
|
||||
*/
|
||||
public final class BooleanLiteral extends Literal {
|
||||
|
||||
/**
|
||||
* True iff I represent True.
|
||||
*/
|
||||
public final boolean value;
|
||||
|
||||
/**
|
||||
* An AST for the token True or False at [LEFT..RIGHT], depending on
|
||||
* VALUE.
|
||||
*/
|
||||
public BooleanLiteral(Location left, Location right, boolean value) {
|
||||
super(left, right);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A function call.
|
||||
*/
|
||||
public class CallExpr extends Expr {
|
||||
|
||||
/**
|
||||
* The called function.
|
||||
*/
|
||||
public final Identifier function;
|
||||
/**
|
||||
* The actual parameter expressions.
|
||||
*/
|
||||
public final List<Expr> args;
|
||||
|
||||
/**
|
||||
* AST for FUNCTION(ARGS) at [LEFT..RIGHT].
|
||||
*/
|
||||
public CallExpr(Location left, Location right, Identifier function,
|
||||
List<Expr> args) {
|
||||
super(left, right);
|
||||
this.function = function;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A class definition.
|
||||
*/
|
||||
public class ClassDef extends Declaration {
|
||||
|
||||
/**
|
||||
* Name of the declared class.
|
||||
*/
|
||||
public final Identifier name;
|
||||
/**
|
||||
* Name of the parent class.
|
||||
*/
|
||||
public final Identifier superClass;
|
||||
/**
|
||||
* Body of the class.
|
||||
*/
|
||||
public final List<Declaration> declarations;
|
||||
|
||||
/**
|
||||
* An AST for class
|
||||
* NAME(SUPERCLASS):
|
||||
* DECLARATIONS.
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public ClassDef(Location left, Location right,
|
||||
Identifier name, Identifier superClass,
|
||||
List<Declaration> declarations) {
|
||||
super(left, right);
|
||||
this.name = name;
|
||||
this.superClass = superClass;
|
||||
this.declarations = declarations;
|
||||
}
|
||||
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIdentifier() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* A simple class type name.
|
||||
*/
|
||||
public final class ClassType extends TypeAnnotation {
|
||||
|
||||
/**
|
||||
* The denotation of the class in source.
|
||||
*/
|
||||
public final String className;
|
||||
|
||||
/**
|
||||
* An AST denoting a type named CLASSNAME0 at [LEFT..RIGHT].
|
||||
*/
|
||||
public ClassType(Location left, Location right, String className0) {
|
||||
super(left, right);
|
||||
className = className0;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a single error. Does not correspond to any Python source
|
||||
* construct.
|
||||
*/
|
||||
public class CompilerError extends Node {
|
||||
|
||||
/**
|
||||
* Represents an error with message MESSAGE. Iff SYNTAX, it is a
|
||||
* syntactic error. The error applies to source text at [LEFT..RIGHT].
|
||||
*/
|
||||
public CompilerError(Location left, Location right, String message,
|
||||
boolean syntax) {
|
||||
super(left, right);
|
||||
this.message = message;
|
||||
this.syntax = syntax;
|
||||
}
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
|
||||
public boolean isSyntax() {
|
||||
return syntax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
CompilerError that = (CompilerError) o;
|
||||
return Objects.equals(message, that.message)
|
||||
&& Arrays.equals(getLocation(), that.getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(message);
|
||||
result = 31 * result + Arrays.hashCode(getLocation());
|
||||
return result;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The error message.
|
||||
*/
|
||||
public final String message;
|
||||
/**
|
||||
* True if this is a syntax error.
|
||||
*/
|
||||
private final boolean syntax;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Base of all AST nodes representing definitions or declarations.
|
||||
*/
|
||||
public abstract class Declaration extends Node {
|
||||
|
||||
/**
|
||||
* A definition or declaration spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public Declaration(Location left, Location right) {
|
||||
super(left, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the identifier defined by this Declaration.
|
||||
*/
|
||||
@JsonIgnore
|
||||
public abstract Identifier getIdentifier();
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Collects the error messages in a Program. There is exactly one per
|
||||
* Program node.
|
||||
*/
|
||||
public class Errors extends Node {
|
||||
|
||||
/**
|
||||
* The accumulated error messages in the order added.
|
||||
*/
|
||||
public final List<CompilerError> errors;
|
||||
|
||||
/**
|
||||
* True iff multiple semantic errors allowed on a node.
|
||||
*/
|
||||
@JsonIgnore
|
||||
private boolean allowMultipleErrors;
|
||||
|
||||
/**
|
||||
* An Errors whose list of CompilerErrors is ERRORS. The list should be
|
||||
* modified using this.add.
|
||||
*/
|
||||
@JsonCreator
|
||||
public Errors(List<CompilerError> errors) {
|
||||
super(null, null);
|
||||
this.errors = errors;
|
||||
allowMultipleErrors = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff there are any errors.
|
||||
*/
|
||||
public boolean hasErrors() {
|
||||
return !this.errors.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent multiple semantic errors on the same node.
|
||||
*/
|
||||
public void suppressMultipleErrors() {
|
||||
allowMultipleErrors = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new semantic error message attributed to NODE, with message
|
||||
* String.format(MESSAGEFORM, ARGS).
|
||||
*/
|
||||
public void semError(Node node, String messageForm, Object... args) {
|
||||
if (allowMultipleErrors || !node.hasError()) {
|
||||
String msg = String.format(messageForm, args);
|
||||
CompilerError err = new CompilerError(null, null, msg, false);
|
||||
err.setLocation(node.getLocation());
|
||||
add(err);
|
||||
if (!node.hasError()) {
|
||||
node.setErrorMsg(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new syntax error message attributed to the source text
|
||||
* between LEFT and RIGHT, and with message
|
||||
* String.format(MESSAGEFORM, ARGS).
|
||||
*/
|
||||
public void syntaxError(Location left, Location right,
|
||||
String messageForm, Object... args) {
|
||||
add(new CompilerError(left, right, String.format(messageForm, args),
|
||||
true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ERR to the list of errors.
|
||||
*/
|
||||
public void add(CompilerError err) {
|
||||
errors.add(err);
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Base of all AST nodes representing expressions.
|
||||
* <p>
|
||||
* There is nothing in this class, but there will be many AST
|
||||
* node types that have fields that are *any expression*. For those
|
||||
* cases, having a field of this type will encompass all types of
|
||||
* expressions such as binary expressions and literals that subclass
|
||||
* this class.
|
||||
*/
|
||||
public abstract class Expr extends Node {
|
||||
|
||||
/**
|
||||
* A Python expression spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public Expr(Location left, Location right) {
|
||||
super(left, right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Statements consisting of expressions.
|
||||
*/
|
||||
public final class ExprStmt extends Stmt {
|
||||
|
||||
/**
|
||||
* The expression I evaluate.
|
||||
*/
|
||||
public final Expr expr;
|
||||
|
||||
/**
|
||||
* The AST for EXPR spanning source locations [LEFT..RIGHT]
|
||||
* in a statement context.
|
||||
*/
|
||||
public ExprStmt(Location left, Location right, Expr expr) {
|
||||
super(left, right);
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* For statements.
|
||||
*/
|
||||
public class ForStmt extends Stmt {
|
||||
/**
|
||||
* Control variable.
|
||||
*/
|
||||
public final Identifier identifier;
|
||||
/**
|
||||
* Source of values of control statement.
|
||||
*/
|
||||
public final Expr iterable;
|
||||
/**
|
||||
* Repeated statements.
|
||||
*/
|
||||
public final List<Stmt> body;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* for IDENTIFIER in ITERABLE:
|
||||
* BODY
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public ForStmt(Location left, Location right,
|
||||
Identifier identifier, Expr iterable, List<Stmt> body) {
|
||||
super(left, right);
|
||||
this.identifier = identifier;
|
||||
this.iterable = iterable;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Def statements.
|
||||
*/
|
||||
public class FuncDef extends Declaration {
|
||||
|
||||
/**
|
||||
* Defined name.
|
||||
*/
|
||||
public final Identifier name;
|
||||
/**
|
||||
* Formal parameters.
|
||||
*/
|
||||
public final List<TypedVar> params;
|
||||
/**
|
||||
* Return type annotation.
|
||||
*/
|
||||
public final TypeAnnotation returnType;
|
||||
/**
|
||||
* Local-variable,inner-function, global, and nonlocal declarations.
|
||||
*/
|
||||
public final List<Declaration> declarations;
|
||||
/**
|
||||
* Other statements.
|
||||
*/
|
||||
public final List<Stmt> statements;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* def NAME(PARAMS) -> RETURNTYPE:
|
||||
* DECLARATIONS
|
||||
* STATEMENTS
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public FuncDef(Location left, Location right,
|
||||
Identifier name, List<TypedVar> params,
|
||||
TypeAnnotation returnType,
|
||||
List<Declaration> declarations, List<Stmt> statements) {
|
||||
super(left, right);
|
||||
this.name = name;
|
||||
this.params = params;
|
||||
this.returnType = returnType;
|
||||
this.declarations = declarations;
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIdentifier() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Declaration of global variable.
|
||||
*/
|
||||
public class GlobalDecl extends Declaration {
|
||||
|
||||
/**
|
||||
* The declared variable.
|
||||
*/
|
||||
public final Identifier variable;
|
||||
|
||||
/**
|
||||
* The AST for the declaration
|
||||
* global VARIABLE
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public GlobalDecl(Location left, Location right, Identifier variable) {
|
||||
super(left, right);
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIdentifier() {
|
||||
return this.variable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* A simple identifier.
|
||||
*/
|
||||
public class Identifier extends Expr {
|
||||
|
||||
/**
|
||||
* Text of the identifier.
|
||||
*/
|
||||
public final String name;
|
||||
|
||||
/**
|
||||
* An AST for the variable, method, or parameter named NAME, spanning
|
||||
* source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public Identifier(Location left, Location right, String name) {
|
||||
super(left, right);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Conditional expressions.
|
||||
*/
|
||||
public class IfExpr extends Expr {
|
||||
/**
|
||||
* Boolean condition.
|
||||
*/
|
||||
public final Expr condition;
|
||||
/**
|
||||
* True branch.
|
||||
*/
|
||||
public final Expr thenExpr;
|
||||
/**
|
||||
* False branch.
|
||||
*/
|
||||
public final Expr elseExpr;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* THENEXPR if CONDITION else ELSEEXPR
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public IfExpr(Location left, Location right,
|
||||
Expr condition, Expr thenExpr, Expr elseExpr) {
|
||||
super(left, right);
|
||||
this.condition = condition;
|
||||
this.thenExpr = thenExpr;
|
||||
this.elseExpr = elseExpr;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Conditional statement.
|
||||
*/
|
||||
public class IfStmt extends Stmt {
|
||||
/**
|
||||
* Test condition.
|
||||
*/
|
||||
public final Expr condition;
|
||||
/**
|
||||
* "True" branch.
|
||||
*/
|
||||
public final List<Stmt> thenBody;
|
||||
/**
|
||||
* "False" branch.
|
||||
*/
|
||||
public final List<Stmt> elseBody;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* if CONDITION:
|
||||
* THENBODY
|
||||
* else:
|
||||
* ELSEBODY
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public IfStmt(Location left, Location right,
|
||||
Expr condition, List<Stmt> thenBody, List<Stmt> elseBody) {
|
||||
super(left, right);
|
||||
this.condition = condition;
|
||||
this.thenBody = thenBody;
|
||||
this.elseBody = elseBody;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* List-indexing expression.
|
||||
*/
|
||||
public class IndexExpr extends Expr {
|
||||
|
||||
/**
|
||||
* Indexed list.
|
||||
*/
|
||||
public final Expr list;
|
||||
/**
|
||||
* Expression for index value.
|
||||
*/
|
||||
public final Expr index;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* LIST[INDEX].
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public IndexExpr(Location left, Location right, Expr list, Expr index) {
|
||||
super(left, right);
|
||||
this.list = list;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Integer numerals.
|
||||
*/
|
||||
public final class IntegerLiteral extends Literal {
|
||||
|
||||
/**
|
||||
* Value denoted.
|
||||
*/
|
||||
public final int value;
|
||||
|
||||
/**
|
||||
* The AST for the literal VALUE, spanning source
|
||||
* locations [LEFT..RIGHT].
|
||||
*/
|
||||
public IntegerLiteral(Location left, Location right, int value) {
|
||||
super(left, right);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* List displays.
|
||||
*/
|
||||
public final class ListExpr extends Expr {
|
||||
|
||||
/**
|
||||
* List of element expressions.
|
||||
*/
|
||||
public final List<Expr> elements;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* [ ELEMENTS ].
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public ListExpr(Location left, Location right, List<Expr> elements) {
|
||||
super(left, right);
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Type denotation for a list type.
|
||||
*/
|
||||
public final class ListType extends TypeAnnotation {
|
||||
|
||||
/**
|
||||
* The element of list element.
|
||||
*/
|
||||
public final TypeAnnotation elementType;
|
||||
|
||||
/**
|
||||
* The AST for the type annotation
|
||||
* [ ELEMENTTYPE ].
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public ListType(Location left, Location right, TypeAnnotation elementType) {
|
||||
super(left, right);
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Base of all the literal nodes.
|
||||
* <p>
|
||||
* There is nothing in this class, but it is useful to isolate
|
||||
* expressions that are constant literals.
|
||||
*/
|
||||
public abstract class Literal extends Expr {
|
||||
/**
|
||||
* A literal spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public Literal(Location left, Location right) {
|
||||
super(left, right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Attribute accessor.
|
||||
*/
|
||||
public class MemberExpr extends Expr {
|
||||
|
||||
/**
|
||||
* Object selected from.
|
||||
*/
|
||||
public final Expr object;
|
||||
/**
|
||||
* Name of attribute (instance variable or method).
|
||||
*/
|
||||
public final Identifier member;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* OBJECT.MEMBER.
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public MemberExpr(Location left, Location right,
|
||||
Expr object, Identifier member) {
|
||||
super(left, right);
|
||||
this.object = object;
|
||||
this.member = member;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Method calls.
|
||||
*/
|
||||
public class MethodCallExpr extends Expr {
|
||||
|
||||
/**
|
||||
* Expression for the bound method to be called.
|
||||
*/
|
||||
public final MemberExpr method;
|
||||
/**
|
||||
* Actual parameters.
|
||||
*/
|
||||
public final List<Expr> args;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* METHOD(ARGS).
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public MethodCallExpr(Location left, Location right,
|
||||
MemberExpr method, List<Expr> args) {
|
||||
super(left, right);
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Root of the AST class hierarchy. Every node has a left and right
|
||||
* location, indicating the start and end of the represented construct
|
||||
* in the source text.
|
||||
* <p>
|
||||
* Every node can be marked with an error message, which serves two purposes:
|
||||
* 1. It indicates that an error message has been issued for this
|
||||
* Node, allowing tne program to reduce cascades of error
|
||||
* messages.
|
||||
* 2. It aids in debugging by making it convenient to see which
|
||||
* Nodes have caused an error.
|
||||
*/
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
|
||||
include = JsonTypeInfo.As.EXISTING_PROPERTY,
|
||||
property = "kind")
|
||||
/* List of all concrete subclasses of Node. */
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(AssignStmt.class),
|
||||
@JsonSubTypes.Type(BinaryExpr.class),
|
||||
@JsonSubTypes.Type(BooleanLiteral.class),
|
||||
@JsonSubTypes.Type(CallExpr.class),
|
||||
@JsonSubTypes.Type(ClassDef.class),
|
||||
@JsonSubTypes.Type(ClassType.class),
|
||||
@JsonSubTypes.Type(CompilerError.class),
|
||||
@JsonSubTypes.Type(Errors.class),
|
||||
@JsonSubTypes.Type(ExprStmt.class),
|
||||
@JsonSubTypes.Type(ForStmt.class),
|
||||
@JsonSubTypes.Type(FuncDef.class),
|
||||
@JsonSubTypes.Type(GlobalDecl.class),
|
||||
@JsonSubTypes.Type(Identifier.class),
|
||||
@JsonSubTypes.Type(IfExpr.class),
|
||||
@JsonSubTypes.Type(IfStmt.class),
|
||||
@JsonSubTypes.Type(IndexExpr.class),
|
||||
@JsonSubTypes.Type(IntegerLiteral.class),
|
||||
@JsonSubTypes.Type(ListExpr.class),
|
||||
@JsonSubTypes.Type(ListType.class),
|
||||
@JsonSubTypes.Type(MemberExpr.class),
|
||||
@JsonSubTypes.Type(MethodCallExpr.class),
|
||||
@JsonSubTypes.Type(NoneLiteral.class),
|
||||
@JsonSubTypes.Type(NonLocalDecl.class),
|
||||
@JsonSubTypes.Type(Program.class),
|
||||
@JsonSubTypes.Type(ReturnStmt.class),
|
||||
@JsonSubTypes.Type(StringLiteral.class),
|
||||
@JsonSubTypes.Type(TypedVar.class),
|
||||
@JsonSubTypes.Type(UnaryExpr.class),
|
||||
@JsonSubTypes.Type(VarDef.class),
|
||||
@JsonSubTypes.Type(WhileStmt.class),
|
||||
})
|
||||
public abstract class Node {
|
||||
|
||||
/**
|
||||
* Node-type indicator for JSON form.
|
||||
*/
|
||||
public final String kind;
|
||||
|
||||
/**
|
||||
* Source position information: 0: line number of start, 1: column number
|
||||
* of start, 2: line number of end, 3: column number of end.
|
||||
*/
|
||||
private final int[] location = new int[4];
|
||||
|
||||
/**
|
||||
* First error message "blamed" on this Node. When non-null, indicates
|
||||
* that an error has been found in this Node.
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private String errorMsg;
|
||||
|
||||
/**
|
||||
* A Node corresponding to source text between LEFT and RIGHT.
|
||||
*/
|
||||
public Node(Location left, Location right) {
|
||||
if (left != null) {
|
||||
location[0] = left.getLine();
|
||||
location[1] = left.getColumn();
|
||||
}
|
||||
if (right != null) {
|
||||
location[2] = right.getLine();
|
||||
location[3] = right.getColumn();
|
||||
}
|
||||
this.kind = getClass().getSimpleName();
|
||||
this.errorMsg = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return my source location as
|
||||
* { <first line>, <first column>, <last line>, <last column> }.
|
||||
* Result should not be modified, and contents will change after
|
||||
* setLocation().
|
||||
*/
|
||||
public int[] getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy LOCATION as getLocation().
|
||||
*/
|
||||
public void setLocation(final int[] location) {
|
||||
System.arraycopy(location, 0, this.location, 0, 4);
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
public void setErrorMsg(String msg) {
|
||||
this.errorMsg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff I have been marked with an error message.
|
||||
*/
|
||||
@JsonIgnore
|
||||
public boolean hasError() {
|
||||
return this.errorMsg != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke ANALYZER on me as a node of static type T. See the comment
|
||||
* on NodeAnalyzer. Returns modified Node.
|
||||
*/
|
||||
public abstract <T> T dispatch(NodeAnalyzer<T> analyzer);
|
||||
|
||||
/**
|
||||
* Print out the AST in JSON format.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return toJSON();
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a serialization of this node in JSON format.
|
||||
*/
|
||||
public String toJSON() throws JsonProcessingException {
|
||||
return mapper.writeValueAsString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapper to-and-from serialized JSON.
|
||||
*/
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
static {
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.registerModule(new ParameterNamesModule());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a T from JSON, a JSON-serialized T value with class
|
||||
* CLAS.
|
||||
*/
|
||||
public static <T> T fromJSON(String json, Class<T> clas)
|
||||
throws IOException {
|
||||
return mapper.readValue(json, clas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of converting JSON, a JSon-serialization of
|
||||
* a Node value, into the value it serializes.
|
||||
*/
|
||||
public static Node fromJSON(String json)
|
||||
throws IOException {
|
||||
return fromJSON(json, Node.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of converting TREE to the value of type T
|
||||
* that it represents, where CLAS reflects T.
|
||||
*/
|
||||
public static <T> T fromJSON(JsonNode tree, Class<T> clas)
|
||||
throws IOException {
|
||||
return mapper.treeToValue(tree, clas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation of serialized value SRC into the
|
||||
* corresponding JSON tree.
|
||||
*/
|
||||
public static JsonNode readTree(String src) throws IOException {
|
||||
return mapper.readTree(src);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Nonlocal declaration.
|
||||
*/
|
||||
public class NonLocalDecl extends Declaration {
|
||||
|
||||
/**
|
||||
* Name of identifier being declared.
|
||||
*/
|
||||
public final Identifier variable;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* nonlocal VARIABLE
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public NonLocalDecl(Location left, Location right, Identifier variable) {
|
||||
super(left, right);
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIdentifier() {
|
||||
return this.variable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* The expression 'None'.
|
||||
*/
|
||||
public final class NoneLiteral extends Literal {
|
||||
|
||||
/**
|
||||
* The AST for None, spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public NoneLiteral(Location left, Location right) {
|
||||
super(left, right);
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An entire ChocoPy program.
|
||||
*/
|
||||
public class Program extends Node {
|
||||
|
||||
/**
|
||||
* Initial variable, class, and function declarations.
|
||||
*/
|
||||
public final List<Declaration> declarations;
|
||||
/**
|
||||
* Trailing statements.
|
||||
*/
|
||||
public final List<Stmt> statements;
|
||||
/**
|
||||
* Accumulated errors.
|
||||
*/
|
||||
public final Errors errors;
|
||||
|
||||
/**
|
||||
* The AST for the program
|
||||
* DECLARATIONS
|
||||
* STATEMENTS
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
* <p>
|
||||
* ERRORS is the container for all error messages applying to the
|
||||
* program.
|
||||
*/
|
||||
public Program(Location left, Location right,
|
||||
List<Declaration> declarations, List<Stmt> statements,
|
||||
Errors errors) {
|
||||
super(left, right);
|
||||
this.declarations = declarations;
|
||||
this.statements = statements;
|
||||
if (errors == null) {
|
||||
this.errors = new Errors(new ArrayList<>());
|
||||
} else {
|
||||
this.errors = errors;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff there is at least one error in the program.
|
||||
*/
|
||||
@JsonIgnore
|
||||
public boolean hasErrors() {
|
||||
return errors.hasErrors();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method returning the list of all CompilerErrors for
|
||||
* this program.
|
||||
*/
|
||||
@JsonIgnore
|
||||
public List<CompilerError> getErrorList() {
|
||||
return errors.errors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Return from function.
|
||||
*/
|
||||
public class ReturnStmt extends Stmt {
|
||||
|
||||
/**
|
||||
* Returned value.
|
||||
*/
|
||||
public final Expr value;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* return VALUE
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public ReturnStmt(Location left, Location right, Expr value) {
|
||||
super(left, right);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Base of all AST nodes representing statements.
|
||||
* <p>
|
||||
* There is nothing in this class, but there will be some AST
|
||||
* node types that have fields that are *any statement* or a
|
||||
* list of statements. For those cases, having a field of this type will
|
||||
* encompass all types of statements such as expression statements,
|
||||
* if statements, while statements, etc.
|
||||
*/
|
||||
public abstract class Stmt extends Node {
|
||||
/**
|
||||
* A statement spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public Stmt(Location left, Location right) {
|
||||
super(left, right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* String constants.
|
||||
*/
|
||||
public final class StringLiteral extends Literal {
|
||||
|
||||
/**
|
||||
* Contents of the literal, not including quotation marks.
|
||||
*/
|
||||
public final String value;
|
||||
|
||||
/**
|
||||
* The AST for a string literal containing VALUE, spanning source
|
||||
* locations [LEFT..RIGHT].
|
||||
*/
|
||||
public StringLiteral(Location left, Location right, String value) {
|
||||
super(left, right);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* Base of all AST nodes representing type annotations (list or class
|
||||
* types.
|
||||
*/
|
||||
public abstract class TypeAnnotation extends Node {
|
||||
/**
|
||||
* An annotation spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public TypeAnnotation(Location left, Location right) {
|
||||
super(left, right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* An identifier with attached type annotation.
|
||||
*/
|
||||
public class TypedVar extends Node {
|
||||
|
||||
/**
|
||||
* The typed identifier.
|
||||
*/
|
||||
public final Identifier identifier;
|
||||
/**
|
||||
* The declared type.
|
||||
*/
|
||||
public final TypeAnnotation type;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* IDENTIFIER : TYPE.
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public TypedVar(Location left, Location right,
|
||||
Identifier identifier, TypeAnnotation type) {
|
||||
super(left, right);
|
||||
this.identifier = identifier;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* An expression applying a unary operator.
|
||||
*/
|
||||
public class UnaryExpr extends Expr {
|
||||
|
||||
/**
|
||||
* The text representation of the operator.
|
||||
*/
|
||||
public final String operator;
|
||||
/**
|
||||
* The operand to which it is applied.
|
||||
*/
|
||||
public final Expr operand;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* OPERATOR OPERAND
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public UnaryExpr(Location left, Location right,
|
||||
String operator, Expr operand) {
|
||||
super(left, right);
|
||||
this.operator = operator;
|
||||
this.operand = operand;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
/**
|
||||
* A declaration of a variable (i.e., with type annotation).
|
||||
*/
|
||||
public class VarDef extends Declaration {
|
||||
/**
|
||||
* The variable and its assigned type.
|
||||
*/
|
||||
public final TypedVar var;
|
||||
/**
|
||||
* The initial value assigned.
|
||||
*/
|
||||
public final Literal value;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* VAR = VALUE
|
||||
* where VAR has a type annotation, and spanning source
|
||||
* locations [LEFT..RIGHT].
|
||||
*/
|
||||
public VarDef(Location left, Location right, TypedVar var, Literal value) {
|
||||
super(left, right);
|
||||
this.var = var;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier defined by this declaration.
|
||||
*/
|
||||
@Override
|
||||
public Identifier getIdentifier() {
|
||||
return this.var.identifier;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package chocopy.common.astnodes;
|
||||
|
||||
import chocopy.common.analysis.NodeAnalyzer;
|
||||
import java_cup.runtime.ComplexSymbolFactory.Location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Indefinite repetition construct.
|
||||
*/
|
||||
public class WhileStmt extends Stmt {
|
||||
/**
|
||||
* Test for whether to continue.
|
||||
*/
|
||||
public final Expr condition;
|
||||
/**
|
||||
* Loop body.
|
||||
*/
|
||||
public final List<Stmt> body;
|
||||
|
||||
/**
|
||||
* The AST for
|
||||
* while CONDITION:
|
||||
* BODY
|
||||
* spanning source locations [LEFT..RIGHT].
|
||||
*/
|
||||
public WhileStmt(Location left, Location right,
|
||||
Expr condition, List<Stmt> body) {
|
||||
super(left, right);
|
||||
this.condition = condition;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
|
||||
public <T> T dispatch(NodeAnalyzer<T> analyzer) {
|
||||
return analyzer.analyze(this);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user