/src/java/ideah/tree/FakeNode.java
http://ideah.googlecode.com/ · Java · 454 lines · 413 code · 27 blank · 14 comment · 125 complexity · a57159da0dd71932b5087bb55a46e519 MD5 · raw file
- package ideah.tree;
-
- import ideah.tree.decl.*;
- import ideah.tree.expr.*;
- import ideah.tree.pat.*;
- import ideah.tree.stmt.BindStmt;
- import ideah.tree.stmt.ExprStmt;
- import ideah.tree.stmt.LetStmt;
- import ideah.tree.stmt.Statement;
- import ideah.tree.type.*;
-
- import java.util.ArrayList;
- import java.util.List;
-
- public final class FakeNode extends Located {
-
- public final String name;
- public final List<FakeNode> children;
-
- public FakeNode(IRange location, String name, List<FakeNode> children) {
- super(location);
- this.name = name;
- this.children = children;
- }
-
- private void append(StringBuilder buf, String indent) {
- buf.append(indent + name + " " + location + " {\n");
- String newIndent = " " + indent;
- for (FakeNode child : children) {
- child.append(buf, newIndent);
- }
- buf.append(indent + "}\n");
- }
-
- public String toString() {
- StringBuilder buf = new StringBuilder();
- append(buf, "");
- return buf.toString();
- }
-
- // todo: range for module!
- ModuleTree toModule(IRange location) throws NoMatchException {
- if ("Module".equals(name)) {
- int i = 0;
- Ident name = null;
- if (i < children.size()) {
- try {
- name = children.get(i).toModuleName();
- i++;
- } catch (NoMatchException ex) {
- // ignore
- }
- }
- List<Export> exports = new ArrayList<Export>();
- while (i < children.size()) {
- FakeNode child = children.get(i);
- try {
- Export export = child.toExport();
- exports.add(export);
- } catch (NoMatchException ex) {
- break;
- }
- i++;
- }
- List<Import> imports = new ArrayList<Import>();
- while (i < children.size()) {
- FakeNode child = children.get(i);
- try {
- Import imp = child.toImport();
- imports.add(imp);
- } catch (NoMatchException ex) {
- break;
- }
- i++;
- }
- List<Declaration> declarations = new ArrayList<Declaration>();
- while (i < children.size()) {
- FakeNode child = children.get(i);
- Declaration declaration = child.toDeclaration();
- declarations.add(declaration);
- i++;
- }
- return new ModuleTree(location, name, exports, imports, declarations);
- } else {
- throw new NoMatchException();
- }
- }
-
- private Ident toModuleName() throws NoMatchException {
- if ("ModuleName".equals(name)) {
- return new Ident(location);
- } else {
- throw new NoMatchException();
- }
- }
-
- private Export toExport() throws NoMatchException {
- if ("Export".equals(name)) {
- return new Export(location);
- } else {
- throw new NoMatchException();
- }
- }
-
- private Import toImport() throws NoMatchException {
- if ("Import".equals(name)) {
- return new Import(location);
- } else {
- throw new NoMatchException();
- }
- }
-
- private Declaration toDeclaration() throws NoMatchException {
- if ("ValD".equals(name)) {
- return children.get(0).toBind();
- } else if ("TyClD".equals(name)) {
- return children.get(0).toTyClDeclaration();
- } else if ("SigD".equals(name)) {
- return children.get(0).toSigDeclaration();
- } else {
- // todo: other cases
- throw new NoMatchException();
- }
- }
-
- private Match toMatch() throws NoMatchException {
- if ("Match".equals(name)) {
- List<Pat> pats = new ArrayList<Pat>();
- int i = 0;
- try {
- children.get(i).toIdent();
- i++;
- } catch (NoMatchException ex) {
- // ignore
- }
- while (i < children.size()) {
- FakeNode child = children.get(i);
- try {
- Pat pattern = child.toPattern();
- pats.add(pattern);
- } catch (NoMatchException ex) {
- break;
- }
- i++;
- }
- GRHSs grhss = toGRHSs(children.subList(i, children.size()));
- return new Match(location, pats, grhss);
- } else {
- throw new NoMatchException();
- }
- }
-
- private static GRHSs toGRHSs(List<FakeNode> nodes) throws NoMatchException {
- int i = 0;
- List<GRHS> grhss = new ArrayList<GRHS>();
- while (i < nodes.size()) {
- FakeNode child = nodes.get(i);
- try {
- GRHS grhs = child.toGRHS();
- grhss.add(grhs);
- } catch (NoMatchException ex) {
- break;
- }
- i++;
- }
- LocalBinds where = toLocalBinds(nodes.subList(i, nodes.size()));
- return new GRHSs(grhss, where);
- }
-
- private static LocalBinds toLocalBinds(List<FakeNode> nodes) throws NoMatchException {
- int i = 0;
- List<Bind> binds = new ArrayList<Bind>();
- while (i < nodes.size()) {
- FakeNode child = nodes.get(i);
- try {
- Bind bind = child.toBind();
- binds.add(bind);
- } catch (NoMatchException ex) {
- break;
- }
- i++;
- }
- List<SigDecl> sigs = new ArrayList<SigDecl>();
- while (i < nodes.size()) {
- FakeNode child = nodes.get(i);
- SigDecl sig = child.toSigDeclaration();
- sigs.add(sig);
- i++;
- }
- return new LocalBinds(binds, sigs);
- }
-
- private Bind toBind() throws NoMatchException {
- if ("FunBind".equals(name)) {
- List<Match> matches = toMatches(children.subList(1, children.size()));
- return new FunctionDecl(location, matches);
- } else if ("PatBind".equals(name)) {
- Pat pattern = children.get(0).toPattern();
- GRHSs grhss = toGRHSs(children.subList(1, children.size()));
- return new PatternDecl(location, pattern, grhss);
- } else {
- throw new NoMatchException();
- }
- }
-
- private GRHS toGRHS() throws NoMatchException {
- if ("GRHS".equals(name)) {
- for (int i = 0; i < children.size() - 1; i++) {
- Statement statement = children.get(i).toStatement();
- // todo: extract guard
- }
- Expression expression = children.get(children.size() - 1).toExpression();
- // todo: statements
- return new GRHS(location, expression);
- } else {
- throw new NoMatchException();
- }
- }
-
- private static List<Match> toMatches(List<FakeNode> nodes) throws NoMatchException {
- List<Match> matches = new ArrayList<Match>();
- for (FakeNode node : nodes) {
- matches.add(node.toMatch());
- }
- return matches;
- }
-
- private Expression toExpression() throws NoMatchException {
- if ("HsOverLit".equals(name)) {
- return new OverLiteral(location);
- } else if ("HsVar".equals(name)) {
- return new VarExpr(location);
- } else if ("HsLit".equals(name)) {
- return new Literal(location);
- } else if ("HsApp".equals(name)) {
- Expression function = children.get(0).toExpression();
- Expression arg = children.get(1).toExpression();
- return new Application(location, function, arg);
- } else if ("SectionL".equals(name)) {
- Expression arg = children.get(0).toExpression();
- Expression op = children.get(1).toExpression();
- return new LeftSection(location, arg, op);
- } else if ("SectionR".equals(name)) {
- Expression op = children.get(0).toExpression();
- Expression arg = children.get(1).toExpression();
- return new RightSection(location, op, arg);
- } else if ("OpApp".equals(name)) {
- Expression left = children.get(0).toExpression();
- Expression op = children.get(1).toExpression();
- Expression right = children.get(2).toExpression();
- return new OpApplication(location, left, op, right);
- } else if ("NegApp".equals(name)) {
- Expression right = children.get(0).toExpression();
- return new Negation(location, right);
- } else if ("HsPar".equals(name)) {
- Expression expression = children.get(0).toExpression();
- return new Parentheses(location, expression);
- } else if ("HsCase".equals(name)) {
- Expression expression = children.get(0).toExpression();
- List<Match> matches = toMatches(children.subList(1, children.size()));
- return new CaseExpr(location, expression, matches);
- } else if ("HsIf".equals(name)) {
- Expression expression = children.get(0).toExpression();
- Expression thenExpr = children.get(1).toExpression();
- Expression elseExpr = children.get(2).toExpression();
- return new IfExpr(location, expression, thenExpr, elseExpr);
- } else if ("HsLam".equals(name)) {
- List<Match> matches = toMatches(children);
- return new Lambda(location, matches);
- } else if ("ExplicitList".equals(name)) {
- List<Expression> expressions = new ArrayList<Expression>();
- for (FakeNode child : children) {
- expressions.add(child.toExpression());
- }
- return new ListExpr(location, expressions);
- } else if ("ExplicitTuple".equals(name)) {
- List<Expression> expressions = new ArrayList<Expression>();
- for (FakeNode child : children) {
- expressions.add(child.toExpression());
- }
- return new TupleExpr(location, expressions);
- } else if ("HsLet".equals(name)) {
- LocalBinds binds = toLocalBinds(children.subList(0, children.size() - 1));
- Expression expression = children.get(children.size() - 1).toExpression();
- return new LetExpr(location, binds, expression);
- } else if ("HsDo".equals(name)) {
- List<Statement> statements = new ArrayList<Statement>();
- for (int i = 0; i < children.size() - 1; i++) {
- Statement statement = children.get(i).toStatement();
- statements.add(statement);
- }
- Expression expression = children.get(children.size() - 1).toExpression();
- return new DoExpr(location, statements, expression);
- } else {
- // todo: RecordCon, RecordUpd, ExprWithTySig, ArithSeq
- // todo: other cases
- throw new NoMatchException();
- }
- }
-
- private Pat toPattern() throws NoMatchException {
- if ("WildPat".equals(name)) {
- return new WildPat(location);
- } else if ("VarPat".equals(name)) {
- return new VarPat(location);
- } else if ("LitPat".equals(name) || "NPat".equals(name)) {
- return new LitPat(location);
- } else if ("ParPat".equals(name)) {
- Pat pattern = children.get(0).toPattern();
- return new ParenPat(location, pattern);
- } else if ("BangPat".equals(name)) {
- Pat pattern = children.get(0).toPattern();
- return new BangPat(location, pattern);
- } else if ("LazyPat".equals(name)) {
- Pat pattern = children.get(0).toPattern();
- return new LazyPat(location, pattern);
- } else if ("ListPat".equals(name)) {
- List<Pat> patterns = new ArrayList<Pat>();
- for (FakeNode child : children) {
- patterns.add(child.toPattern());
- }
- return new ListPat(location, patterns);
- } else if ("TuplePat".equals(name)) {
- List<Pat> patterns = new ArrayList<Pat>();
- for (FakeNode child : children) {
- patterns.add(child.toPattern());
- }
- return new TuplePat(location, patterns);
- } else if ("AsPat".equals(name)) {
- Ident name = children.get(0).toIdent();
- Pat pattern = children.get(1).toPattern();
- return new AsPat(location, name, pattern);
- } else if ("ConPatIn".equals(name)) {
- Ident name = children.get(0).toIdent();
- List<Pat> patterns = new ArrayList<Pat>();
- for (int i = 1; i < children.size(); i++) {
- FakeNode child = children.get(i);
- Pat pattern = child.toPattern();
- patterns.add(pattern);
- }
- return new ConPat(location, name, new ConPatDetails(patterns)); // todo: records?
- } else {
- // todo: other cases
- throw new NoMatchException();
- }
- }
-
- private Statement toStatement() throws NoMatchException {
- if ("BindStmt".equals(name)) {
- Pat pattern = children.get(0).toPattern();
- Expression expression = children.get(1).toExpression();
- return new BindStmt(location, pattern, expression);
- } else if ("ExprStmt".equals(name)) {
- Expression expression = children.get(0).toExpression();
- return new ExprStmt(location, expression);
- } else if ("LetStmt".equals(name)) {
- LocalBinds binds = toLocalBinds(children);
- return new LetStmt(location, binds);
- } else {
- // todo: other cases
- throw new NoMatchException();
- }
- }
-
- private Type toType() throws NoMatchException {
- if ("HsForAllTy".equals(name)) {
- Type type = children.get(0).toType();
- return new ForAllType(location, type);
- } else if ("HsTyVar".equals(name)) {
- return new TyVarType(location);
- } else if ("HsAppTy".equals(name)) {
- Type type = children.get(0).toType();
- Type arg = children.get(1).toType();
- return new AppTyType(location, type, arg);
- } else if ("HsFunTy".equals(name)) {
- Type arg = children.get(0).toType();
- Type result = children.get(1).toType();
- return new FuncType(location, arg, result);
- } else if ("HsListTy".equals(name)) {
- Type type = children.get(0).toType();
- return new ListType(location, type);
- } else if ("HsTupleTy".equals(name)) {
- List<Type> types = new ArrayList<Type>();
- for (FakeNode child : children) {
- types.add(child.toType());
- }
- return new TupleType(location, types);
- } else if ("HsBangTy".equals(name)) {
- Type type = children.get(0).toType();
- return new BangType(location, type);
- } else {
- // todo: HsOpTy, HsRecTy
- // todo: other cases
- throw new NoMatchException();
- }
- }
-
- private SigDecl toSigDeclaration() throws NoMatchException {
- if ("TypeSig".equals(name)) {
- Ident name = children.get(0).toIdent();
- Type type = children.get(1).toType();
- return new TypeSigDecl(location, name, type);
- } else {
- // todo: other cases
- throw new NoMatchException();
- }
- }
-
- private TyClDecl toTyClDeclaration() throws NoMatchException {
- if ("TySynonym".equals(name)) {
- Ident name = children.get(0).toIdent();
- Type type = children.get(1).toType();
- return new TypeSynDecl(location, name, type);
- } else if ("TyData".equals(name)) {
- Ident name = children.get(0).toIdent();
- List<ConDecl> constructors = new ArrayList<ConDecl>();
- for (int i = 1; i < children.size(); i++) {
- ConDecl cons = children.get(i).toConDeclaration();
- constructors.add(cons);
- }
- return new DataTypeDecl(location, name, constructors);
- } else {
- // todo: other cases
- throw new NoMatchException();
- }
- }
-
- private ConDecl toConDeclaration() throws NoMatchException {
- if ("ConDecl".equals(name)) {
- Ident name = children.get(0).toIdent();
- List<Type> types = new ArrayList<Type>();
- for (int i = 1; i < children.size(); i++) {
- FakeNode child = children.get(i);
- Type type = child.toType();
- types.add(type);
- }
- return new ConDecl(location, name, types);
- } else {
- throw new NoMatchException();
- }
- }
-
- private Ident toIdent() throws NoMatchException {
- if ("Id".equals(name)) {
- return new Ident(location);
- } else {
- throw new NoMatchException();
- }
- }
-
- protected Iterable<FakeNode> getChildren() {
- return children;
- }
- }