Package org.yinwang.yin

Source Code of org.yinwang.yin.Binder

package org.yinwang.yin;


import org.yinwang.yin.ast.*;
import org.yinwang.yin.value.RecordType;
import org.yinwang.yin.value.Value;
import org.yinwang.yin.value.Vector;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Binder {

    public static void define(Node pattern, Value value, Scope env) {
        if (pattern instanceof Name) {
            String id = ((Name) pattern).id;
            Value v = env.lookupLocal(id);
            if (v != null) {
                Util.abort(pattern, "trying to redefine name: " + id);
            } else {
                env.putValue(id, value);
            }
        } else if (pattern instanceof RecordLiteral) {
            if (value instanceof RecordType) {
                Map<String, Node> elms1 = ((RecordLiteral) pattern).map;
                Scope elms2 = ((RecordType) value).properties;
                if (elms1.keySet().equals(elms2.keySet())) {
                    for (String k1 : elms1.keySet()) {
                        define(elms1.get(k1), elms2.lookupLocal(k1), env);
                    }
                } else {
                    Util.abort(pattern, "define with records of different attributes: " +
                            elms1.keySet() + " v.s. " + elms2.keySet());
                }
            } else {
                Util.abort(pattern, "define with incompatible types: record and " + value);
            }
        } else if (pattern instanceof VectorLiteral) {
            if (value instanceof Vector) {
                List<Node> elms1 = ((VectorLiteral) pattern).elements;
                List<Value> elms2 = ((Vector) value).values;
                if (elms1.size() == elms2.size()) {
                    for (int i = 0; i < elms1.size(); i++) {
                        define(elms1.get(i), elms2.get(i), env);
                    }
                } else {
                    Util.abort(pattern,
                            "define with vectors of different sizes: " + elms1.size() + " v.s. " + elms2.size());
                }
            } else {
                Util.abort(pattern, "define with incompatible types: vector and " + value);
            }
        } else {
            Util.abort(pattern, "unsupported pattern of define: " + pattern);
        }
    }


    public static void assign(Node pattern, Value value, Scope env) {
        if (pattern instanceof Name) {
            String id = ((Name) pattern).id;
            Scope d = env.findDefiningScope(id);

            if (d == null) {
                Util.abort(pattern, "assigned name was not defined: " + id);
            } else {
                d.putValue(id, value);
            }
        } else if (pattern instanceof Subscript) {
            ((Subscript) pattern).set(value, env);
        } else if (pattern instanceof Attr) {
            ((Attr) pattern).set(value, env);
        } else if (pattern instanceof RecordLiteral) {
            if (value instanceof RecordType) {
                Map<String, Node> elms1 = ((RecordLiteral) pattern).map;
                Scope elms2 = ((RecordType) value).properties;
                if (elms1.keySet().equals(elms2.keySet())) {
                    for (String k1 : elms1.keySet()) {
                        assign(elms1.get(k1), elms2.lookupLocal(k1), env);
                    }
                } else {
                    Util.abort(pattern, "assign with records of different attributes: " +
                            elms1.keySet() + " v.s. " + elms2.keySet());
                }
            } else {
                Util.abort(pattern, "assign with incompatible types: record and " + value);
            }
        } else if (pattern instanceof VectorLiteral) {
            if (value instanceof Vector) {
                List<Node> elms1 = ((VectorLiteral) pattern).elements;
                List<Value> elms2 = ((Vector) value).values;
                if (elms1.size() == elms2.size()) {
                    for (int i = 0; i < elms1.size(); i++) {
                        assign(elms1.get(i), elms2.get(i), env);
                    }
                } else {
                    Util.abort(pattern, "assign vectors of different sizes: " + elms1.size() + " v.s. " + elms2.size());
                }
            } else {
                Util.abort(pattern, "assign incompatible types: vector and " + value);
            }
        } else {
            Util.abort(pattern, "unsupported pattern of assign: " + pattern);
        }
    }


    public static void checkDup(Node pattern) {
        checkDup1(pattern, new HashSet<String>());
    }


    public static void checkDup1(Node pattern, Set<String> seen) {

        if (pattern instanceof Name) {
            String id = ((Name) pattern).id;
            if (seen.contains(id)) {
                Util.abort(pattern, "duplicated name found in pattern: " + pattern);
            } else {
                seen.add(id);
            }
        } else if (pattern instanceof RecordLiteral) {
            for (Node v : ((RecordLiteral) pattern).map.values()) {
                checkDup1(v, seen);
            }
        } else if (pattern instanceof VectorLiteral) {
            for (Node v : ((VectorLiteral) pattern).elements) {
                checkDup1(v, seen);
            }
        }
    }

}
TOP

Related Classes of org.yinwang.yin.Binder

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.