Mercurial Hosting > luan
comparison src/luan/interp/ExpList.java @ 154:c2e5101682ae
Expr extends Expressions
git-svn-id: https://luan-java.googlecode.com/svn/trunk@155 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Tue, 17 Jun 2014 09:55:43 +0000 |
parents | 14281d5bd36f |
children |
comparison
equal
deleted
inserted
replaced
153:fa03671f59a0 | 154:c2e5101682ae |
---|---|
1 package luan.interp; | 1 package luan.interp; |
2 | 2 |
3 import java.util.List; | 3 import java.util.List; |
4 import java.util.ArrayList; | 4 import java.util.ArrayList; |
5 import java.util.Collections; | 5 import java.util.Arrays; |
6 import luan.LuanException; | 6 import luan.LuanException; |
7 import luan.LuanSource; | 7 import luan.LuanSource; |
8 import luan.LuanFunction; | |
9 import luan.Luan; | |
8 | 10 |
9 | 11 |
10 final class ExpList implements Expressions { | 12 final class ExpList { |
11 | |
12 private interface Adder { | |
13 public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException; | |
14 public Code code(); | |
15 } | |
16 | |
17 private static class ExprAdder implements Adder { | |
18 private final Expr expr; | |
19 | |
20 ExprAdder(Expr expr) { | |
21 this.expr = expr; | |
22 } | |
23 | |
24 public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException { | |
25 list.add( expr.eval(luan) ); | |
26 } | |
27 | |
28 public Code code() { | |
29 return expr; | |
30 } | |
31 | |
32 } | |
33 | |
34 private static class ExpressionsAdder implements Adder { | |
35 private final Expressions expressions; | |
36 | |
37 ExpressionsAdder(Expressions expressions) { | |
38 this.expressions = expressions; | |
39 } | |
40 | |
41 public void addTo(LuanStateImpl luan,List<Object> list) throws LuanException { | |
42 Object obj = expressions.eval(luan); | |
43 if( obj instanceof Object[] ) { | |
44 for( Object val : (Object[])obj ) { | |
45 list.add( val ); | |
46 } | |
47 } else { | |
48 list.add(obj); | |
49 } | |
50 } | |
51 | |
52 public Code code() { | |
53 return expressions; | |
54 } | |
55 | |
56 } | |
57 | |
58 static class Builder { | |
59 private final List<Adder> adders = new ArrayList<Adder>(); | |
60 | |
61 void add(Expr expr) { | |
62 if( expr==null ) | |
63 throw new NullPointerException(); | |
64 adders.add( new ExprAdder(expr) ); | |
65 } | |
66 | |
67 void add(Expressions expressions) { | |
68 adders.add( new ExpressionsAdder(expressions) ); | |
69 } | |
70 | |
71 void add(Code code) { | |
72 if( code instanceof Expr ) { | |
73 add((Expr)code); | |
74 } else { | |
75 add((Expressions)code); | |
76 } | |
77 } | |
78 | |
79 Expressions build() { | |
80 int size = adders.size(); | |
81 if( size == 0 ) | |
82 return emptyExpList; | |
83 if( size == 1 ) { | |
84 Adder adder = adders.get(0); | |
85 if( adder instanceof ExpressionsAdder ) { | |
86 ExpressionsAdder ea = (ExpressionsAdder)adder; | |
87 return ea.expressions; | |
88 } | |
89 ExprAdder ea = (ExprAdder)adder; | |
90 return new SingleExpList(ea.expr); | |
91 } | |
92 Adder[] a = adders.toArray(new Adder[size]); | |
93 for( int i=0; i<size-1; i++ ) { | |
94 Adder adder = a[i]; | |
95 if( adder instanceof ExpressionsAdder ) { | |
96 a[i] = new ExprAdder(new ExpressionsExpr(((ExpressionsAdder)adder).expressions)); | |
97 } | |
98 } | |
99 return new ExpList(a); | |
100 } | |
101 } | |
102 | |
103 private static final Object[] EMPTY = new Object[0]; | |
104 | 13 |
105 static final Expressions emptyExpList = new Expressions() { | 14 static final Expressions emptyExpList = new Expressions() { |
106 | 15 |
107 @Override public Object[] eval(LuanStateImpl luan) { | 16 @Override public Object[] eval(LuanStateImpl luan) { |
108 return EMPTY; | 17 return LuanFunction.NOTHING; |
109 } | 18 } |
110 | 19 |
111 @Override public LuanSource.Element se() { | 20 @Override public LuanSource.Element se() { |
112 return null; | 21 return null; |
113 } | 22 } |
114 }; | 23 }; |
115 | 24 |
116 static class SingleExpList implements Expressions { | 25 static Expr[] toArray(List<Expressions> list) { |
117 private final Expr expr; | 26 Expr[] a = new Expr[list.size()]; |
27 for( int i=0; i<a.length; i++ ) { | |
28 Expressions exprs = list.get(i); | |
29 if( exprs instanceof Expr ) { | |
30 a[i] = (Expr)exprs; | |
31 } else { | |
32 a[i] = new ExpressionsExpr(exprs); | |
33 } | |
34 } | |
35 return a; | |
36 } | |
118 | 37 |
119 SingleExpList(Expr expr) { | 38 static Expressions build(List<Expressions> list) { |
120 this.expr = expr; | 39 switch(list.size()) { |
121 } | 40 case 0: |
122 | 41 return emptyExpList; |
123 @Override public Object eval(LuanStateImpl luan) throws LuanException { | 42 case 1: |
124 //System.out.println("SingleExpList "+expr); | 43 return list.get(0); |
125 return expr.eval(luan); | 44 default: |
126 } | 45 if( list.get(list.size()-1) instanceof Expr ) { |
127 | 46 return new ExprList1( toArray(list) ); |
128 @Override public LuanSource.Element se() { | 47 } else { |
129 return expr.se(); | 48 Expressions last = list.remove(list.size()-1); |
130 } | 49 return new ExprList2( toArray(list), last ); |
131 | 50 } |
132 @Override public String toString() { | |
133 return "(SingleExpList "+expr+")"; | |
134 } | 51 } |
135 } | 52 } |
136 | 53 |
137 private final Adder[] adders; | 54 private static class ExprList1 implements Expressions { |
55 private final Expr[] exprs; | |
138 | 56 |
139 private ExpList(Adder[] adders) { | 57 private ExprList1(Expr[] exprs) { |
140 this.adders = adders; | 58 this.exprs = exprs; |
141 } | |
142 | |
143 @Override public Object eval(LuanStateImpl luan) throws LuanException { | |
144 List<Object> list = new ArrayList<Object>(); | |
145 for( Adder adder : adders ) { | |
146 adder.addTo(luan,list); | |
147 } | 59 } |
148 switch( list.size() ) { | 60 |
149 case 0: | 61 @Override public Object eval(LuanStateImpl luan) throws LuanException { |
150 return EMPTY; | 62 Object[] a = new Object[exprs.length]; |
151 case 1: | 63 for( int i=0; i<exprs.length; i++ ) { |
152 return list.get(0); | 64 a[i] = exprs[i].eval(luan); |
153 default: | 65 } |
154 return list.toArray(); | 66 return a; |
67 } | |
68 | |
69 @Override public LuanSource.Element se() { | |
70 return new LuanSource.Element(exprs[0].se().source,exprs[0].se().start,exprs[exprs.length-1].se().end); | |
155 } | 71 } |
156 } | 72 } |
157 | 73 |
158 @Override public LuanSource.Element se() { | 74 private static class ExprList2 implements Expressions { |
159 return new LuanSource.Element(adders[0].code().se().source,adders[0].code().se().start,adders[adders.length-1].code().se().end); | 75 private final Expr[] exprs; |
76 private final Expressions last; | |
77 | |
78 private ExprList2(Expr[] exprs,Expressions last) { | |
79 this.exprs = exprs; | |
80 this.last = last; | |
81 } | |
82 | |
83 @Override public Object eval(LuanStateImpl luan) throws LuanException { | |
84 List<Object> list = new ArrayList<Object>(); | |
85 for( Expr expr : exprs ) { | |
86 list.add( expr.eval(luan) ); | |
87 } | |
88 list.addAll( Arrays.asList(Luan.array( last.eval(luan) )) ); | |
89 return list.toArray(); | |
90 } | |
91 | |
92 @Override public LuanSource.Element se() { | |
93 return new LuanSource.Element(exprs[0].se().source,exprs[0].se().start,last.se().end); | |
94 } | |
160 } | 95 } |
161 } | 96 } |