
public class Call extends Stmt {
	public Name op;
	public Argument args;

	public Call(Name op, Argument args) {
		super();
		this.op = op;
		this.args = args;
	}

	@Override
	public Value interp(Scope s) {
		Value opv = op.interp(s);
		if (opv instanceof Closure) {
			Closure closure = (Closure) opv;
			// 注意继承每个函数共享的初始envScope
			Scope funScope = new Scope(closure.env);
			if (args.size() != closure.fun.params.size()) {
				S.error("调用参数不匹配: " + this);
			}
			ListValue lv = args.interp(funScope);

			for (int i = 0; i < closure.fun.params.size(); i++) {
				funScope.putValue(closure.fun.params.get(i).id, lv.get(i));
			}
			// 所有return语句的地方都以异常ReturnJmp传递返回值
			Value v = Value.VOID;
			try {
				closure.fun.body.interp(funScope);
			} catch (ReturnJmp e) { // 返回值 通过异常可以使return语句在某一个函数内的任意block中都能成功返回
									// 唉 实是无奈之举啊
				return e.attatchment();//
			}
			return v;
		} else if (opv instanceof BuiltinFun) {
			BuiltinFun fun = (BuiltinFun) opv;
			//
			// List<Value> args = new ArrayList<>(this.args.elements.size());
			// for (Node node : this.args.elements) {
			// args.add(node.interp(s));
			// }
			return fun.apply(args.interp(s).values);
		} else {
			S.error("不支持的调用" + opv);
			return Value.VOID; // never touch
		}
	}

	@Override
	public Value typecheck(Scope s) {
		Value opv = op.interp(s);
		if (opv instanceof BuiltinFun || opv instanceof Closure)
			return opv;
		else
			S.error("不支持的调用类型：" + opv);
		return Value.VOID; // never touch
	}

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

}

@@ -668,33 +668,8 @@
 %E8%BF%94%E5%9B%9E%E5%80%BC%0A
-%09%09%09Value v = Value.VOID;%0A
 %09%09%09t
@@ -677,16 +677,23 @@
 y %7B%0A%09%09%09%09
+return 
 closure.
@@ -794,30 +794,14 @@
 %E6%88%90%E5%8A%9F%E8%BF%94%E5%9B%9E
-%0A%09%09%09%09%09%09%09%09%09// %E5%94%89 %E5%AE%9E%E6%98%AF%E6%97%A0%E5%A5%88%E4%B9%8B%E4%B8%BE%E5%95%8A
+(%E5%8C%85%E6%8B%AC%E7%BB%93%E5%B0%BE)
 %0A%09%09%09
@@ -830,26 +830,25 @@
 );//
-%0A%09%09%09%7D%0A%09%09%09return v;
+// %E5%94%89 %E5%AE%9E%E6%98%AF%E6%97%A0%E5%A5%88%E4%B9%8B%E4%B8%BE%E5%95%8A%0A%09%09%09%7D
 %0A%09%09%7D
@@ -931,69 +931,28 @@
 %0A%09%09%09
-//%0A%09%09%09// List%3CValue%3E args = new ArrayList%3C%3E(this.args.element
+if (fun.arity != arg
 s.si
@@ -960,93 +960,47 @@
 e())
-;
+ %7B
 %0A%09%09%09
-// for (Node node : this.args.elements) %7B%0A%09%09%09// args.add(node.interp(s)
+%09S.error(%22%E8%B0%83%E7%94%A8%E5%8F%82%E6%95%B0%E4%B8%8D%E5%8C%B9%E9%85%8D: %22 + this
 );%0A%09%09%09
-// 
 %7D%0A%09%09

verify built-in function args match