Package ideah.tree

Source Code of ideah.tree.FakeNode

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;
    }
}
TOP

Related Classes of ideah.tree.FakeNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.