comparison src/luan/LuanTable.java @ 1267:9fa8b8389578

add LuanTable.luan; support metatable __gc(); add luan.sql;
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 12 Nov 2018 02:10:41 -0700
parents 73d754b1889f
children 503bde9a7c80
comparison
equal deleted inserted replaced
1266:05934fbf635a 1267:9fa8b8389578
12 import java.util.Set; 12 import java.util.Set;
13 import java.util.HashSet; 13 import java.util.HashSet;
14 14
15 15
16 public final class LuanTable implements LuanCloneable { 16 public final class LuanTable implements LuanCloneable {
17 private LuanState luan;
17 private Map map = null; 18 private Map map = null;
18 private List list = null; 19 private List list = null;
19 private LuanTable metatable = null; 20 private LuanTable metatable = null;
20 public LuanJavaOk javaOk; 21 public LuanJavaOk javaOk;
21 private LuanCloner cloner; 22 private LuanCloner cloner;
22 23
23 public LuanTable() {} 24 public LuanTable(LuanState luan) {
24 25 this.luan = luan;
25 public LuanTable(List list) { 26 }
27
28 public LuanTable(LuanState luan,List list) {
26 int n = list.size(); 29 int n = list.size();
27 for( int i=0; i<n; i++ ) { 30 for( int i=0; i<n; i++ ) {
28 Object val = list.get(i); 31 Object val = list.get(i);
29 if( val != null ) 32 if( val != null )
30 rawPut(i+1,val); 33 rawPut(i+1,val);
31 } 34 }
32 } 35 }
33 36
34 public LuanTable(Map map) { 37 public LuanTable(LuanState luan,Map map) {
38 this.luan = luan;
35 for( Object stupid : map.entrySet() ) { 39 for( Object stupid : map.entrySet() ) {
36 Map.Entry entry = (Map.Entry)stupid; 40 Map.Entry entry = (Map.Entry)stupid;
37 Object key = entry.getKey(); 41 Object key = entry.getKey();
38 Object value = entry.getValue(); 42 Object value = entry.getValue();
39 if( key != null && value != null ) 43 if( key != null && value != null )
40 rawPut(key,value); 44 rawPut(key,value);
41 } 45 }
42 } 46 }
43 47
44 public LuanTable(Set set) { 48 public LuanTable(LuanState luan,Set set) {
49 this.luan = luan;
45 for( Object el : set ) { 50 for( Object el : set ) {
46 if( el != null ) 51 if( el != null )
47 rawPut(el,Boolean.TRUE); 52 rawPut(el,Boolean.TRUE);
48 } 53 }
49 } 54 }
50 55
51 public LuanTable(LuanTable tbl) { 56 public LuanTable(LuanTable tbl) {
57 this.luan = tbl.luan;
52 if( tbl.map != null && !tbl.map.isEmpty() ) 58 if( tbl.map != null && !tbl.map.isEmpty() )
53 this.map = new LinkedHashMap<Object,Object>(tbl.map); 59 this.map = new LinkedHashMap<Object,Object>(tbl.map);
54 if( tbl.rawLength() > 0 ) 60 if( tbl.rawLength() > 0 )
55 this.list = new ArrayList<Object>(tbl.list); 61 this.list = new ArrayList<Object>(tbl.list);
56 this.metatable = tbl.metatable; 62 this.metatable = tbl.metatable;
57 } 63 }
58 64
59 @Override public LuanTable shallowClone() { 65 @Override public LuanTable shallowClone() {
60 return new LuanTable(); 66 return new LuanTable(luan);
61 } 67 }
62 68
63 @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { 69 @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
64 check(); 70 check();
65 LuanTable clone = (LuanTable)dc; 71 LuanTable clone = (LuanTable)dc;
83 cloner = null; 89 cloner = null;
84 } 90 }
85 } 91 }
86 92
87 private void deepenClone(LuanTable clone,LuanCloner cloner) { 93 private void deepenClone(LuanTable clone,LuanCloner cloner) {
94 clone.luan = (LuanState)cloner.clone(luan);
88 if( map != null ) { 95 if( map != null ) {
89 Map newMap = newMap(); 96 Map newMap = newMap();
90 for( Object stupid : map.entrySet() ) { 97 for( Object stupid : map.entrySet() ) {
91 Map.Entry entry = (Map.Entry)stupid; 98 Map.Entry entry = (Map.Entry)stupid;
92 newMap.put( cloner.get(entry.getKey()), cloner.get(entry.getValue()) ); 99 newMap.put( cloner.get(entry.getKey()), cloner.get(entry.getValue()) );
116 public Map rawMap() { 123 public Map rawMap() {
117 check(); 124 check();
118 return map!=null ? map : Collections.emptyMap(); 125 return map!=null ? map : Collections.emptyMap();
119 } 126 }
120 127
121 public String toString(LuanState luan) throws LuanException { 128 public String toStringLuan() throws LuanException {
122 Object h = getHandler(luan,"__to_string"); 129 Object h = getHandler("__to_string");
123 if( h == null ) 130 if( h == null )
124 return rawToString(); 131 return rawToString();
125 LuanFunction fn = Luan.checkFunction(h); 132 LuanFunction fn = Luan.checkFunction(h);
126 return Luan.checkString( Luan.first( fn.call(luan,new Object[]{this}) ) ); 133 return Luan.checkString( Luan.first( fn.call(luan,new Object[]{this}) ) );
127 } 134 }
128 135
129 public String rawToString() { 136 public String rawToString() {
130 return "table: " + Integer.toHexString(hashCode()); 137 return "table: " + Integer.toHexString(hashCode());
131 } 138 }
132 139
133 public Object get(LuanState luan,Object key) throws LuanException { 140 public Object get(Object key) throws LuanException {
134 Object value = rawGet(key); 141 Object value = rawGet(key);
135 if( value != null ) 142 if( value != null )
136 return value; 143 return value;
137 Object h = getHandler(luan,"__index"); 144 Object h = getHandler("__index");
138 if( h==null ) 145 if( h==null )
139 return null; 146 return null;
140 if( h instanceof LuanFunction ) { 147 if( h instanceof LuanFunction ) {
141 LuanFunction fn = (LuanFunction)h; 148 LuanFunction fn = (LuanFunction)h;
142 return Luan.first(fn.call(luan,new Object[]{this,key})); 149 return Luan.first(fn.call(luan,new Object[]{this,key}));
161 key = Double.valueOf(n.doubleValue()); 168 key = Double.valueOf(n.doubleValue());
162 } 169 }
163 return map.get(key); 170 return map.get(key);
164 } 171 }
165 172
166 public void put(LuanState luan,Object key,Object value) throws LuanException { 173 public void put(Object key,Object value) throws LuanException {
167 Object h = getHandler(luan,"__new_index"); 174 Object h = getHandler("__new_index");
168 if( h==null || rawGet(key)!=null ) { 175 if( h==null || rawGet(key)!=null ) {
169 rawPut(key,value); 176 rawPut(key,value);
170 return; 177 return;
171 } 178 }
172 if( h instanceof LuanFunction ) { 179 if( h instanceof LuanFunction ) {
174 fn.call(luan,new Object[]{this,key,value}); 181 fn.call(luan,new Object[]{this,key,value});
175 return; 182 return;
176 } 183 }
177 if( h instanceof LuanTable ) { 184 if( h instanceof LuanTable ) {
178 LuanTable tbl = (LuanTable)h; 185 LuanTable tbl = (LuanTable)h;
179 tbl.put(luan,key,value); 186 tbl.put(key,value);
180 return; 187 return;
181 } 188 }
182 throw new LuanException("invalid type "+Luan.type(h)+" for metamethod __new_index"); 189 throw new LuanException("invalid type "+Luan.type(h)+" for metamethod __new_index");
183 } 190 }
184 191
265 public void rawSort(Comparator<Object> cmp) { 272 public void rawSort(Comparator<Object> cmp) {
266 check(); 273 check();
267 Collections.sort(list(),cmp); 274 Collections.sort(list(),cmp);
268 } 275 }
269 276
270 public int length(LuanState luan) throws LuanException { 277 public int length() throws LuanException {
271 Object h = getHandler(luan,"__len"); 278 Object h = getHandler("__len");
272 if( h != null ) { 279 if( h != null ) {
273 LuanFunction fn = Luan.checkFunction(h); 280 LuanFunction fn = Luan.checkFunction(h);
274 return (Integer)Luan.first(fn.call(luan,new Object[]{this})); 281 return (Integer)Luan.first(fn.call(luan,new Object[]{this}));
275 } 282 }
276 return rawLength(); 283 return rawLength();
279 public int rawLength() { 286 public int rawLength() {
280 check(); 287 check();
281 return list==null ? 0 : list.size(); 288 return list==null ? 0 : list.size();
282 } 289 }
283 290
284 public Iterable<Map.Entry> iterable(LuanState luan) throws LuanException { 291 public Iterable<Map.Entry> iterable() throws LuanException {
285 final Iterator<Map.Entry> iter = iterator(luan); 292 final Iterator<Map.Entry> iter = iterator();
286 return new Iterable<Map.Entry>() { 293 return new Iterable<Map.Entry>() {
287 public Iterator<Map.Entry> iterator() { 294 public Iterator<Map.Entry> iterator() {
288 return iter; 295 return iter;
289 } 296 }
290 }; 297 };
297 return iter; 304 return iter;
298 } 305 }
299 }; 306 };
300 } 307 }
301 308
302 public Iterator<Map.Entry> iterator(final LuanState luan) throws LuanException { 309 public Iterator<Map.Entry> iterator() throws LuanException {
303 if( getHandler(luan,"__pairs") == null ) 310 if( getHandler("__pairs") == null )
304 return rawIterator(); 311 return rawIterator();
305 final LuanFunction fn = pairs(luan); 312 final LuanFunction fn = pairs();
306 return new Iterator<Map.Entry>() { 313 return new Iterator<Map.Entry>() {
307 private Map.Entry<Object,Object> next = getNext(); 314 private Map.Entry<Object,Object> next = getNext();
308 315
309 private Map.Entry<Object,Object> getNext() { 316 private Map.Entry<Object,Object> getNext() {
310 try { 317 try {
334 throw new UnsupportedOperationException(); 341 throw new UnsupportedOperationException();
335 } 342 }
336 }; 343 };
337 } 344 }
338 345
339 public LuanFunction pairs(LuanState luan) throws LuanException { 346 public LuanFunction pairs() throws LuanException {
340 Object h = getHandler(luan,"__pairs"); 347 Object h = getHandler("__pairs");
341 if( h != null ) { 348 if( h != null ) {
342 if( h instanceof LuanFunction ) { 349 if( h instanceof LuanFunction ) {
343 LuanFunction fn = (LuanFunction)h; 350 LuanFunction fn = (LuanFunction)h;
344 Object obj = Luan.first(fn.call(luan,new Object[]{this})); 351 Object obj = Luan.first(fn.call(luan,new Object[]{this}));
345 if( !(obj instanceof LuanFunction) ) 352 if( !(obj instanceof LuanFunction) )
418 }; 425 };
419 } 426 }
420 427
421 public LuanTable rawSubList(int from,int to) { 428 public LuanTable rawSubList(int from,int to) {
422 check(); 429 check();
423 LuanTable tbl = new LuanTable(); 430 LuanTable tbl = new LuanTable(luan);
424 tbl.list = new ArrayList<Object>(list().subList(from-1,to-1)); 431 tbl.list = new ArrayList<Object>(list().subList(from-1,to-1));
425 return tbl; 432 return tbl;
426 } 433 }
427 434
428 public LuanTable getMetatable() { 435 public LuanTable getMetatable() {
433 public void setMetatable(LuanTable metatable) { 440 public void setMetatable(LuanTable metatable) {
434 check(); 441 check();
435 this.metatable = metatable; 442 this.metatable = metatable;
436 } 443 }
437 444
438 public Object getHandler(LuanState luan,String op) throws LuanException { 445 public Object getHandler(String op) throws LuanException {
439 check(); 446 check();
440 return metatable==null ? null : metatable.get(luan,op); 447 return metatable==null ? null : metatable.get(op);
441 } 448 }
442 449
443 private Map<Object,Object> newMap() { 450 private Map<Object,Object> newMap() {
444 return new LinkedHashMap<Object,Object>(); 451 return new LinkedHashMap<Object,Object>();
445 } 452 }
446 453
447 public boolean isSet(LuanState luan) throws LuanException { 454 public boolean isSet() throws LuanException {
448 for( Map.Entry<Object,Object> entry : iterable(luan) ) { 455 for( Map.Entry<Object,Object> entry : iterable() ) {
449 if( !entry.getValue().equals(Boolean.TRUE) ) 456 if( !entry.getValue().equals(Boolean.TRUE) )
450 return false; 457 return false;
451 } 458 }
452 return true; 459 return true;
453 } 460 }
454 461
455 public Set<Object> asSet(LuanState luan) throws LuanException { 462 public Set<Object> asSet() throws LuanException {
456 Set<Object> set = new HashSet<Object>(); 463 Set<Object> set = new HashSet<Object>();
457 for( Map.Entry<Object,Object> entry : iterable(luan) ) { 464 for( Map.Entry<Object,Object> entry : iterable() ) {
458 set.add(entry.getKey()); 465 set.add(entry.getKey());
459 } 466 }
460 return set; 467 return set;
461 } 468 }
462 469
463 public Map<Object,Object> asMap(LuanState luan) throws LuanException { 470 public Map<Object,Object> asMap() throws LuanException {
464 Map<Object,Object> map = newMap(); 471 Map<Object,Object> map = newMap();
465 for( Map.Entry<Object,Object> entry : iterable(luan) ) { 472 for( Map.Entry<Object,Object> entry : iterable() ) {
466 map.put(entry.getKey(),entry.getValue()); 473 map.put(entry.getKey(),entry.getValue());
467 } 474 }
468 return map; 475 return map;
469 } 476 }
470 477
493 n += map.size(); 500 n += map.size();
494 if( list != null ) 501 if( list != null )
495 n += list.size(); 502 n += list.size();
496 return n; 503 return n;
497 } 504 }
505
506 protected void finalize() throws Throwable {
507 Object h = getHandler("__gc");
508 if( h != null ) {
509 LuanFunction fn = Luan.checkFunction(h);
510 fn.call(luan,new Object[]{this});
511 }
512 super.finalize();
513 }
514
498 } 515 }