01: package gnu.kawa.functions;
02:
03: import gnu.lists.*;
04: import gnu.mapping.*;
05: import gnu.bytecode.*;
06: import gnu.expr.*;
07:
08: /**
09: * Implement the Scheme standard function "list".
10: * @author Per Bothner
11: */
12:
13: public class MakeList extends ProcedureN implements Inlineable {
14: public static final MakeList list = new MakeList();
15: static {
16: list.setName("list");
17: }
18:
19: public static Object list$V(Object[] args) {
20: Object result = LList.Empty;
21: for (int i = args.length; --i >= 0;)
22: result = new Pair(args[i], result);
23: return result;
24: }
25:
26: public Object applyN(Object[] args) {
27: return list$V(args);
28: }
29:
30: public void compile(ApplyExp exp, Compilation comp, Target target) {
31: Expression[] args = exp.getArgs();
32: compile(args, 0, comp);
33: target.compileFromStack(comp, getReturnType(args));
34: }
35:
36: public static void compile(Expression[] args, int offset,
37: Compilation comp) {
38: int len = args.length - offset;
39: CodeAttr code = comp.getCode();
40: if (len == 0) {
41: new QuoteExp(LList.Empty).compile(comp, Target.pushObject);
42: } else if (len <= 4) {
43: for (int i = 0; i < len; i++)
44: args[offset + i].compile(comp, Target.pushObject);
45: Method method = Compilation.scmListType.getDeclaredMethod(
46: "list" + len, null);
47: code.emitInvokeStatic(method);
48: } else {
49: args[offset].compile(comp, Target.pushObject);
50: Method method = Compilation.scmListType.getDeclaredMethod(
51: "list1", null);
52: code.emitInvokeStatic(method);
53: code.emitDup(1);
54: offset++;
55: len--;
56:
57: while (len >= 4) {
58: args[offset].compile(comp, Target.pushObject);
59: args[offset + 1].compile(comp, Target.pushObject);
60: args[offset + 2].compile(comp, Target.pushObject);
61: args[offset + 3].compile(comp, Target.pushObject);
62: len -= 4;
63: offset += 4;
64: method = Compilation.scmListType.getDeclaredMethod(
65: "chain4", null);
66: code.emitInvokeStatic(method);
67: }
68:
69: while (len > 0) {
70: args[offset].compile(comp, Target.pushObject);
71: len -= 1;
72: offset += 1;
73: method = Compilation.scmListType.getDeclaredMethod(
74: "chain1", null);
75: code.emitInvokeStatic(method);
76: }
77: code.emitPop(1);
78: }
79: }
80:
81: public Type getReturnType(Expression[] args) {
82: return args.length > 0 ? Compilation.scmPairType
83: : Compilation.scmListType;
84: }
85:
86: }
|