Package litil.eval

Source Code of litil.eval.Prelude

package litil.eval;

import litil.TypeScope;
import litil.ast.DataDecl;
import litil.ast.Type;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Prelude {

    public static Adt Nil = new Adt("Nil", Collections.emptyList()) {

        @Override
        public String toString() {
            return "[]";
        }
    };

    public static ValScope rootScope() {
        ValScope res = new ValScope();
        res.define("-/1", new Fn() {
            public Object eval(Object arg, ValScope scope) {
                return -(Long) arg;
            }
        });
        res.define("not", new Fn() {
            public Object eval(Object arg, ValScope scope) {
                return !(Boolean) arg;
            }
        });
        res.define("+", new Fn() {
            public Object eval(final Object arg1, ValScope scope) {
                Fn fn = new Fn() {
                    public Object eval(Object arg2, ValScope scope) {
                        return (Long) arg1 + (Long) arg2;
                    }

                    @Override
                    public String toString() {
                        return "+(int, int)";
                    }
                };
                return fn;
            }

            @Override
            public String toString() {
                return "+(int)";
            }
        });

        res.define("-", new Fn() {
            public Object eval(final Object arg1, ValScope scope) {
                Fn fn = new Fn() {
                    public Object eval(Object arg2, ValScope scope) {
                        return (Long) arg1 - (Long) arg2;
                    }

                    @Override
                    public String toString() {
                        return "-(int, int)";
                    }
                };
                return fn;
            }

            @Override
            public String toString() {
                return "+(int)";
            }
        });

        res.define("*", new Fn() {
            public Object eval(final Object arg1, ValScope scope) {
                Fn fn = new Fn() {
                    public Object eval(Object arg2, ValScope scope) {
                        return (Long) arg1 * (Long) arg2;
                    }

                    @Override
                    public String toString() {
                        return "*(int, int)";
                    }
                };
                return fn;
            }

            @Override
            public String toString() {
                return "+(int)";
            }
        });

        res.define("=", new Fn.BiFn() {
            @Override
            protected Object eval(Object arg1, Object arg2, ValScope scope) {
                return arg1.equals(arg2);
            }
        });


        res.define("print", new Fn() {
            public Object eval(Object arg, ValScope scope) {
                System.out.println(">> " + arg);
                return null;
            }
        });

        res.define("int2str", new Fn() {
            public Object eval(Object arg, ValScope scope) {
                return arg + "";
            }
        });

        res.define("<", new Fn.BiFn() {
            @Override
            protected Object eval(Object arg1, Object arg2, ValScope scope) {
                return (Long) arg1 < (Long) arg2;
            }
        });
        res.define(">", new Fn.BiFn() {
            @Override
            protected Object eval(Object arg1, Object arg2, ValScope scope) {
                return (Long) arg1 > (Long) arg2;
            }
        });

        res.define("%", new Fn.BiFn() {
            @Override
            protected Object eval(Object arg1, Object arg2, ValScope scope) {
                return (Long) arg1 % (Long) arg2;
            }
        });

        res.define("error", new Fn() {
            public Object eval(Object arg, ValScope scope) {
                throw new RuntimeException((String) arg);
            }
        });

        res.define("Cons", new Fn.BiFn() {
            @Override
            protected Object eval(Object arg1, Object arg2, ValScope scope) {
                return Cons(arg1, arg2);
            }


        });

        res.define("Nil", Nil);

        return res;
    }

    public static Adt Cons(final Object head, final Object tail) {
        return new Adt("Cons", Arrays.asList(head, tail)) {
            private List<Object> toList(Adt adt) {
                List<Object> items = new ArrayList<Object>();
                if ("Nil".equals(adt.tag)) {
                    return Collections.emptyList();
                } else {
                    items.add(adt.args.get(0));
                    items.addAll(toList((Adt) adt.args.get(1)));
                    return items;
                }
            }

            @Override
            public String toString() {
                return toList(this) + "";
            }
        };
    }

    public static TypeScope trootScope() {
        TypeScope res = new TypeScope();
        res.define("-/1", Type.Function(Type.INT, Type.INT));
        res.define("not", Type.Function(Type.BOOL, Type.BOOL));
        res.define("+", Type.Function(Arrays.asList(Type.INT, Type.INT), Type.INT));
        res.define("-", Type.Function(Arrays.asList(Type.INT, Type.INT), Type.INT));
        res.define("*", Type.Function(Arrays.asList(Type.INT, Type.INT), Type.INT));
        res.define("/", Type.Function(Arrays.asList(Type.INT, Type.INT), Type.INT));
        res.define("%", Type.Function(Arrays.asList(Type.INT, Type.INT), Type.INT));

        res.define(">", Type.Function(Arrays.asList(Type.INT, Type.INT), Type.BOOL));
        res.define("<", Type.Function(Arrays.asList(Type.INT, Type.INT), Type.BOOL));

        Type.Variable a = new Type.Variable();
        res.define("=", Type.Function(Arrays.asList(a, a), Type.BOOL));

        res.define("int2str", Type.Function(Type.INT, Type.STR));
        res.define("print", Type.Function(Type.STR, Type.UNIT));
        res.define("error", Type.Function(Type.STR, new Type.Variable()));

        Type.Variable b = new Type.Variable();
        Type listType = Type.List(b);
        List<DataDecl.TypeConstructor> listConstructors = new ArrayList<DataDecl.TypeConstructor>();
        List<Type> listVars = Arrays.<Type>asList(b);
        listConstructors.add(new DataDecl.TypeConstructor("Cons", Arrays.asList(b, listType)));
        listConstructors.add(new DataDecl.TypeConstructor("Nil"));
        DataDecl list = new DataDecl("List", listType, Arrays.asList(b), listConstructors);

        for (DataDecl.TypeConstructor tyCon : listConstructors) {
            res.define(tyCon.name, Type.TyCon(tyCon, list));
        }
        return res;
    }

}
TOP

Related Classes of litil.eval.Prelude

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.