All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hydra.tools.PrettyPrinter Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
package hydra.tools;

import hydra.core.AnnotatedTerm;
import hydra.core.FloatValue;
import hydra.core.Function;
import hydra.core.IntegerValue;
import hydra.core.Lambda;
import hydra.core.Literal;
import hydra.core.Name;
import hydra.core.Term;
import hydra.core.WrappedTerm;
import hydra.lib.literals.ShowString;
import hydra.util.Opt;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;


/**
 * A temporary pretty-printer for terms, for the sake of tests and debugging. In the future, JSON should be used.
 */
public class PrettyPrinter {
    private PrettyPrinter() {
    }

    /**
     * Serialize a term to a string.
     */
    public static  String printTerm(Term t) {
        StringBuilder sb = new StringBuilder();
        term(t).accept(sb);
        return sb.toString();
    }

    private static Consumer brackets(String open, String close,
        List> consumers) {
        return sb -> {
            sb.append(open);
            boolean first = true;
            for (Consumer c : consumers) {
                if (first) {
                    first = false;
                } else {
                    sb.append(", ");
                }
                c.accept(sb);
            }
            sb.append(close);
        };
    }

    private static Consumer floatValue(FloatValue f) {
        return f.accept(new FloatValue.Visitor>() {
            @Override
            public Consumer visit(FloatValue.Bigfloat instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(FloatValue.Float32 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(FloatValue.Float64 instance) {
                return sb -> sb.append(instance.value);
            }
        });
    }

    private static  Consumer function(hydra.core.Function function) {
        return function.accept(new Function.Visitor>() {
            @Override
            public Consumer visit(Function.Elimination instance) {
                return notImplemented("elimination");
            }

            @Override
            public Consumer visit(Function.Lambda instance) {
                Lambda lam = instance.value;
                return sb -> {
                    sb.append("\"").append(shortName(lam.parameter)).append(" -> ");
                    term(lam.body).accept(sb);
                };
            }

            @Override
            public Consumer visit(Function.Primitive instance) {
                return sb -> sb.append(shortName(instance.value)).append("!");
            }
        });
    }

    private static Consumer integerValue(IntegerValue i) {
        return i.accept(new IntegerValue.Visitor>() {
            @Override
            public Consumer visit(IntegerValue.Bigint instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Int16 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Int32 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Int64 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Int8 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Uint16 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Uint32 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Uint64 instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(IntegerValue.Uint8 instance) {
                return sb -> sb.append(instance.value);
            }
        });
    }

    private static Consumer literal(Literal l) {
        return l.accept(new Literal.Visitor>() {
            @Override
            public Consumer visit(Literal.Binary instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(Literal.Boolean_ instance) {
                return sb -> sb.append(instance.value);
            }

            @Override
            public Consumer visit(Literal.Float_ instance) {
                return floatValue(instance.value);
            }

            @Override
            public Consumer visit(Literal.Integer_ instance) {
                return integerValue(instance.value);
            }

            @Override
            public Consumer visit(Literal.String_ instance) {
                return sb -> sb.append(ShowString.apply(instance.value));
            }
        });
    }

    private static Consumer notImplemented(String name) {
        return sb -> sb.append("(").append(name).append(")");
    }

    private static Consumer parens(Consumer... consumers) {
        return parens(Arrays.asList(consumers));
    }

    private static Consumer parens(List> consumers) {
        return brackets("(", ")", consumers);
    }

    private static String shortName(Name name) {
        String s = name.value;
        int i = s.lastIndexOf('.');
        return i < 0 ? s : s.substring(i + 1);
    }

    private static Consumer squareBrackets(List> consumers) {
        return brackets("[", "]", consumers);
    }

    private static Consumer term(Term t) {
        return sb -> {
            Consumer c = t.accept(new Term.Visitor>() {
                @Override
                public Consumer visit(Term.Annotated instance) {
                    AnnotatedTerm ann = instance.value;
                    Consumer ac = sb1 -> sb1.append(ann.annotation.toString());
                    return var("annot", term(ann.subject), ac);
                }

                @Override
                public Consumer visit(Term.Application instance) {
                    return var("apply", term(instance.value.function), term(instance.value.argument));
                }

                @Override
                public Consumer visit(Term.Function instance) {
                    return function(instance.value);
                }

                @Override
                public Consumer visit(Term.Let instance) {
                    return notImplemented("let");
                }

                @Override
                public Consumer visit(Term.List instance) {
                    List list = instance.value;
                    List> cs =
                        list.stream().map(PrettyPrinter::term).collect(Collectors.toList());
                    return squareBrackets(cs);
                }

                @Override
                public Consumer visit(Term.Literal instance) {
                    return literal(instance.value);
                }

                @Override
                public Consumer visit(Term.Map instance) {
                    return notImplemented("map");
                }

                @Override
                public Consumer visit(Term.Optional instance) {
                    Opt opt = instance.value;
                    return sb -> {
                        if (opt.isPresent()) {
                            var("just", term(opt.get())).accept(sb);
                        } else {
                            sb.append("nothing");
                        }
                    };
                }

                @Override
                public Consumer visit(Term.Product instance) {
                    return notImplemented("product");
                }

                @Override
                public Consumer visit(Term.Record instance) {
                    return notImplemented("record");
                }

                @Override
                public Consumer visit(Term.Set instance) {
                    return notImplemented("set");
                }

                @Override
                public Consumer visit(Term.Sum instance) {
                    return notImplemented("sum");
                }

                @Override
                public Consumer visit(Term.Typed instance) {
                    return notImplemented("typed");
                }

                @Override
                public Consumer visit(Term.Union instance) {
                    return notImplemented("union");
                }

                @Override
                public Consumer visit(Term.Variable instance) {
                    return sb -> sb.append("?").append(shortName(instance.value));
                }

                @Override
                public Consumer visit(Term.Wrap instance) {
                    WrappedTerm nom = instance.value;
                    return var(shortName(nom.typeName), term(nom.object));
                }
            });

            if (c != null) {
                c.accept(sb);
            }
        };
    }

    private static Consumer var(String name, Consumer... consumers) {
        return sb -> {
            sb.append(name);
            parens(consumers).accept(sb);
        };
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy