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 }