From 42585abb29cd1c18ba4ddca7dca842c43bff8935 Mon Sep 17 00:00:00 2001 From: Yin Wang Date: Sun, 2 Feb 2014 02:40:24 -0800 Subject: [PATCH] apply Declare.evalProperties to functions with properties --- src/main/java/org/yinwang/yin/ast/Call.java | 8 ++++++- .../java/org/yinwang/yin/ast/Declare.java | 21 ++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/yinwang/yin/ast/Call.java b/src/main/java/org/yinwang/yin/ast/Call.java index 8f941f1..8349ba0 100644 --- a/src/main/java/org/yinwang/yin/ast/Call.java +++ b/src/main/java/org/yinwang/yin/ast/Call.java @@ -23,15 +23,21 @@ public Call(Node func, Argument args, String file, int start, int end, int line, public Value interp(Scope s) { Value fun = this.func.interp(s); if (fun instanceof Closure) { + Fun def = ((Closure) fun).fun; Closure closure = (Closure) fun; Scope funScope = new Scope(closure.env); List params = closure.fun.params; + if (def.properties != null) { + Declare.evalProperties(def.properties, funScope); + } + if (!args.positional.isEmpty() && args.keywords.isEmpty()) { // positional if (args.positional.size() != params.size()) { _.abort(this.func, - "calling function with wrong number of arguments: " + args.positional.size()); + "calling function with wrong number of arguments. expected: " + params.size() + + " actual: " + args.positional.size()); } for (int i = 0; i < args.positional.size(); i++) { diff --git a/src/main/java/org/yinwang/yin/ast/Declare.java b/src/main/java/org/yinwang/yin/ast/Declare.java index 77e06bc..82687f0 100644 --- a/src/main/java/org/yinwang/yin/ast/Declare.java +++ b/src/main/java/org/yinwang/yin/ast/Declare.java @@ -3,11 +3,8 @@ import org.yinwang.yin.Constants; import org.yinwang.yin.Scope; import org.yinwang.yin._; -import org.yinwang.yin.parser.Parser; import org.yinwang.yin.value.Value; -import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; @@ -23,6 +20,16 @@ public Declare(Scope propsNode, String file, int start, int end, int line, int c public Value interp(Scope s) { + evalProperties(propsNode, s); + return Value.VOID; + } + + + // helper + // evaluate the properties inside propsNode + // then merge into the Scope s + public static void evalProperties(Scope propsNode, Scope s) { + // evaluate the properties Scope properties = new Scope(); for (String field : propsNode.keySet()) { Map props = propsNode.lookupAllProps(field); @@ -32,13 +39,15 @@ public Value interp(Scope s) { Value vValue = ((Node) v).interp(s); properties.put(field, e.getKey(), vValue); } else { - _.abort(this, "property is not a node, parser bug: " + v); + _.abort("property is not a node, parser bug: " + v); } } } + // merge the properties into current scope s.putAll(properties); + // set default values for variables for (String key : properties.keySet()) { Object defaultValue = properties.lookupPropertyLocal(key, "default"); if (defaultValue == null) { @@ -49,11 +58,9 @@ public Value interp(Scope s) { s.putValue(key, (Value) defaultValue); } } else { - _.abort("default value is not value, shouldn't happen"); + _.abort("default value is not a value, shouldn't happen"); } } - - return Value.VOID; }