package ast;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import ast.Ast.Atom;
import ast.Ast.HasPos;
import ast.Ast.Position;
import ast.Ast.SignalKind;
import ast.Ast.Type;
import ast.Ast.VarDec;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
import lombok.experimental.Wither;
public interface Expression extends Ast {
public <T> T accept(sugarVisitors.Visitor<T> v);
@Value public static class Signal implements Expression {
SignalKind kind;
Expression inner;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class Loop implements Expression {
Expression inner;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") @Wither public static class If implements Expression, HasPos {
Position p;
Expression cond;
Expression then;
Optional<Expression> _else;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class While implements Expression, HasPos {
Position p;
Expression cond;
Expression then;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") @Wither public static class With implements Expression, HasPos {
Position p;
List<String> xs;
List<VarDecXE> is;
List<VarDecXE> decs;
List<On> ons;
Optional<Expression> defaultE;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
@Value
@Wither
public static class On {
List<Type> ts;
Expression inner;
}
}
@Value @EqualsAndHashCode(exclude = "p")
public static class X implements Expression, Ast.Atom, HasPos{
Position p;
String inner;
public String toString() {
return this.inner;
}
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class ContextId implements Expression, Ast.Atom {
String inner;//contains the "\"
public String toString() {
return this.inner;
}
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @EqualsAndHashCode(exclude = "p") /*@ToString(exclude = "p")*/ @Wither public static class BinOp implements Expression, HasPos {
Position p;
Expression left;
Ast.Op op;
Expression right;
public String toString() {
return "(" + left + op.inner + right + ")";
}
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class DocE implements Expression {
Expression inner;
Doc doc;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @EqualsAndHashCode(exclude = "p") /*@ToString(exclude = "p")*/ public static class UnOp implements Expression, HasPos {
Position p;
Ast.Op op;
Expression inner;
public String toString() {
return "(" + op.inner + inner + ")";
}
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @Wither @EqualsAndHashCode(exclude = {"p"}) @ToString(exclude = {"p"}) public static class MCall implements Expression, HasPos,HasReceiver {
Expression receiver;
String name;
Doc doc;
Parameters ps;
Position p;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class FCall implements Expression, HasPos, HasReceiver {
@NonNull Position p;
Expression receiver;
Doc doc;
Parameters ps;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class SquareCall implements Expression, HasPos,HasReceiver {
Position p;
Expression receiver;
Doc doc;
List<Doc> docs;
List<Parameters> pss;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class SquareWithCall implements Expression, HasPos,HasReceiver {
Position p;
Expression receiver;
With with;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class UseSquare implements Expression{
Expression inner;//is either SquareCall with void receiver or With
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
public static interface Catch extends HasPos{
<T> T match(Function<Catch1, T> k1,Function<CatchMany, T> kM,Function<CatchProp, T> kP);
String getX();
Expression getInner();
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class Catch1 implements Catch{
Position p;
SignalKind kind;
Type t;
String x;
Expression inner;
public <T> T match(Function<Catch1, T> k1,Function<CatchMany, T> kM,Function<CatchProp, T> kP){return k1.apply(this);}
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class CatchMany implements Catch{
Position p;
SignalKind kind;
List<Type> ts;
Expression inner;
public String getX(){return "";}
public <T> T match(Function<Catch1, T> k1,Function<CatchMany, T> kM,Function<CatchProp, T> kP){return kM.apply(this);}
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class CatchProp implements Catch{
Position p;
SignalKind kind;
List<Type> ts;
Expression inner;
public String getX(){return "";}
public <T> T match(Function<Catch1, T> k1,Function<CatchMany, T> kM,Function<CatchProp, T> kP){return kP.apply(this);}
}
@Value
public class BlockContent {
List<VarDec> decs;
List<Catch> _catch;
}
@Value @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") @Wither public static class RoundBlock implements Expression, HasPos {
Position p;
Doc doc;
Expression inner;
List<BlockContent> contents;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class CurlyBlock implements Expression, HasPos {
Position p;
Doc doc;
List<BlockContent> contents;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class Using implements Expression {
Path path;
String name;
Doc docs;
Parameters ps;
Expression inner;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @Wither public static class ClassReuse implements Expression, Ast.Atom {
ClassB inner;
String url;
ExpCore.ClassB urlFetched;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
//TODO: for decent error messages, eventually we have to admit duplicated members in Expression, so that the well formedess function can have an input
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class ClassB implements Expression, Ast.Atom, HasPos{
public ClassB(Doc doc1, Header h, List<Ast.FieldDec> fields, List<Type> supertypes, List<Member> ms,Position p) {
this.doc1 = doc1;
this.h = h;
this.fields=fields;
this.supertypes = supertypes;
this.ms = ms;
this.p=p;
isConsistent();
}
Doc doc1;
Header h;
List<Ast.FieldDec> fields;
List<Type> supertypes;
List<Member> ms;
Position p;
public boolean isConsistent() {
HashSet<String> keys = new HashSet<String>();
int countWalkBy = 0;
for (Member m : this.ms) {
if (m instanceof MethodWithType) {
MethodWithType mwt = (MethodWithType) m;
String key=mwt.getMs().toString();
//For better error messages we would like to finish parsing
//assert !keys.contains(key);
keys.add(key);
}
if (m instanceof NestedClass) {
NestedClass nc = (NestedClass) m;
String key=nc.getName().toString();
//For better error messages we would like to finish parsing
//assert !keys.contains(key);
keys.add(key);
if (nc.inner instanceof WalkBy) {
countWalkBy += 1;
}
}
}
assert countWalkBy <= 1 : this;
return true;
}
//public String toString() {
// return sugarVisitors.ToFormattedText.of(this);
//}
public interface Member extends HasPos{
<T> T match(Function<NestedClass, T> nc, Function<MethodImplemented, T> mi, Function<MethodWithType, T> mt);
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p")public static class NestedClass implements Member {
Doc doc;
Ast.C name;
Expression inner;
Ast.Position p;
public <T> T match(Function<NestedClass, T> nc, Function<MethodImplemented, T> mi, Function<MethodWithType, T> mt) {
return nc.apply(this);
}
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p")public static class MethodImplemented implements Member {
Doc doc;
MethodSelector s;
Expression inner;
Ast.Position p;
public <T> T match(Function<NestedClass, T> nc, Function<MethodImplemented, T> mi, Function<MethodWithType, T> mt) {
return mi.apply(this);
}
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p")public static class MethodWithType implements Member {
Doc doc;
MethodSelector ms;
MethodType mt;
Optional<Expression> inner;
Ast.Position p;
public <T> T match(Function<NestedClass, T> nc, Function<MethodImplemented, T> mi, Function<MethodWithType, T> mt) {
return mt.apply(this);
}
}
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class DotDotDot implements Expression {
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class WalkBy implements Expression {
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value @Wither @EqualsAndHashCode(exclude = "p")
public static class EPath implements Expression,HasPos,Atom{
Position p;
Ast.Path inner;
public String toString(){return this.getInner().toString();}
public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
@Value public static class _void implements Expression, Ast.Atom {
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
public static final _void instance=new _void();
}
@Value @Wither @EqualsAndHashCode(exclude = "p") @ToString(exclude = "p") public static class Literal implements Expression, HasPos,HasReceiver {
Position p;
Expression receiver;
String inner;
boolean isNumber;
@Override public <T> T accept(sugarVisitors.Visitor<T> v) {
return v.visit(this);
}
}
}