Package org.yinwang.yin

Examples of org.yinwang.yin.Scope


    public Value interp(Scope s) {
        Value opv = this.op.interp(s);
        if (opv instanceof Closure) {
            Closure closure = (Closure) opv;
            Scope funScope = new Scope(closure.env);
            List<Name> params = closure.fun.params;

            // set default values for parameters
            if (closure.properties != null) {
                Declare.mergeDefault(closure.properties, funScope);
            }

            if (!args.positional.isEmpty() && args.keywords.isEmpty()) {
                for (int i = 0; i < args.positional.size(); i++) {
                    Value value = args.positional.get(i).interp(s);
                    funScope.putValue(params.get(i).id, value);
                }
            } else {
                // try to bind all arguments
                for (Name param : params) {
                    Node actual = args.keywords.get(param.id);
                    if (actual != null) {
                        Value value = actual.interp(funScope);
                        funScope.putValue(param.id, value);
                    }
                }
            }
            return closure.fun.body.interp(funScope);
        } else if (opv instanceof RecordType) {
            RecordType template = (RecordType) opv;
            Scope values = new Scope();

            // set default values for fields
            Declare.mergeDefault(template.properties, values);

            // instantiate
View Full Code Here


        Value fun = this.op.typecheck(s);
        if (fun instanceof FunType) {
            FunType funtype = (FunType) fun;
//            TypeChecker.self.uncalled.remove(funtype);

            Scope funScope = new Scope(funtype.env);
            List<Name> params = funtype.fun.params;

            // set default values for parameters
            if (funtype.properties != null) {
                Declare.mergeType(funtype.properties, funScope);
            }

            if (!args.positional.isEmpty() && args.keywords.isEmpty()) {
                // positional
                if (args.positional.size() != params.size()) {
                    Util.abort(this.op,
                            "calling function with wrong number of arguments. expected: " + params.size()
                                    + " actual: " + args.positional.size());
                }

                for (int i = 0; i < args.positional.size(); i++) {
                    Value value = args.positional.get(i).typecheck(s);
                    Value expected = funScope.lookup(params.get(i).id);
                    if (!Type.subtype(value, expected, false)) {
                        Util.abort(args.positional.get(i), "type error. expected: " + expected + ", actual: " + value);
                    }
                    funScope.putValue(params.get(i).id, value);
                }
            } else {
                // keywords
                Set<String> seen = new HashSet<>();

                // try to bind all arguments
                for (Name param : params) {
                    Node actual = args.keywords.get(param.id);
                    if (actual != null) {
                        seen.add(param.id);
                        Value value = actual.typecheck(funScope);
                        Value expected = funScope.lookup(param.id);
                        if (!Type.subtype(value, expected, false)) {
                            Util.abort(actual, "type error. expected: " + expected + ", actual: " + value);
                        }
                        funScope.putValue(param.id, value);
                    } else {
                        Util.abort(this, "argument not supplied for: " + param);
                        return Value.VOID;
                    }
                }

                // detect extra arguments
                List<String> extra = new ArrayList<>();
                for (String id : args.keywords.keySet()) {
                    if (!seen.contains(id)) {
                        extra.add(id);
                    }
                }

                if (!extra.isEmpty()) {
                    Util.abort(this, "extra keyword arguments: " + extra);
                    return Value.VOID;
                }
            }

            Object retType = funtype.properties.lookupPropertyLocal(Constants.RETURN_ARROW, "type");
            if (retType != null) {
                if (retType instanceof Node) {
                    // evaluate the return type because it might be (typeof x)
                    return ((Node) retType).typecheck(funScope);
                } else {
                    Util.abort("illegal return type: " + retType);
                    return null;
                }
            } else {
                if (TypeChecker.self.callStack.contains(fun)) {
                    Util.abort(op, "You must specify return type for recursive functions: " + op);
                    return null;
                }

                TypeChecker.self.callStack.add((FunType) fun);
                Value actual = funtype.fun.body.typecheck(funScope);
                TypeChecker.self.callStack.remove(fun);
                return actual;
            }
        } else if (fun instanceof RecordType) {
            RecordType template = (RecordType) fun;
            Scope values = new Scope();

            // set default values for fields
            Declare.mergeDefault(template.properties, values);

            // set actual values, overwrite defaults if any
            for (Map.Entry<String, Node> e : args.keywords.entrySet()) {
                if (!template.properties.keySet().contains(e.getKey())) {
                    Util.abort(this, "extra keyword argument: " + e.getKey());
                }

                Value actual = args.keywords.get(e.getKey()).typecheck(s);
                Value expected = template.properties.lookupLocalType(e.getKey());
                if (!Type.subtype(actual, expected, false)) {
                    Util.abort(this, "type error. expected: " + expected + ", actual: " + actual);
                }
                values.putValue(e.getKey(), e.getValue().typecheck(s));
            }

            // check uninitialized fields
            for (String field : template.properties.keySet()) {
                if (values.lookupLocal(field) == null) {
                    Util.abort(this, "field is not initialized: " + field);
                }
            }

            // instantiate
View Full Code Here

        this.statements = statements;
    }


    public Value interp(Scope s) {
        s = new Scope(s);
        for (int i = 0; i < statements.size() - 1; i++) {
            statements.get(i).interp(s);
        }
        return statements.get(statements.size() - 1).interp(s);
    }
View Full Code Here

    }


    @Override
    public Value typecheck(Scope s) {
        s = new Scope(s);
        for (int i = 0; i < statements.size() - 1; i++) {
            statements.get(i).typecheck(s);
        }
        return statements.get(statements.size() - 1).typecheck(s);
    }
View Full Code Here

        }
    }


    public Value interp(Scope s) {
        Scope properties = new Scope();
        for (Map.Entry<String, Node> e : map.entrySet()) {
            properties.putValue(e.getKey(), e.getValue().interp(s));
        }
        return new RecordType(null, this, properties);
    }
View Full Code Here

    }


    @Override
    public Value typecheck(Scope s) {
        Scope properties = new Scope();
        for (Map.Entry<String, Node> e : map.entrySet()) {
            properties.putValue(e.getKey(), e.getValue().typecheck(s));
        }
        return new RecordType(null, this, properties);
    }
View Full Code Here

TOP

Related Classes of org.yinwang.yin.Scope

Copyright © 2018 www.massapicom. 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.