Mercurial Hosting > luan
comparison src/luan/LuanTable.java @ 1563:8fbcc4747091
remove LuanFunction.luan
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 09 Nov 2020 01:37:57 -0700 |
parents | b89212fd04b5 |
children | 364859d29ff5 |
comparison
equal
deleted
inserted
replaced
1562:b89212fd04b5 | 1563:8fbcc4747091 |
---|---|
18 private List list = null; | 18 private List list = null; |
19 private LuanTable metatable = null; | 19 private LuanTable metatable = null; |
20 public LuanClosure closure; | 20 public LuanClosure closure; |
21 private LuanCloner cloner; | 21 private LuanCloner cloner; |
22 private boolean immutable = false; | 22 private boolean immutable = false; |
23 private Luan luan; | |
23 | 24 |
24 public LuanTable() {} | 25 public LuanTable() {} |
25 | 26 |
26 public LuanTable(List list) { | 27 public LuanTable(List list) { |
27 try { | 28 try { |
97 completeClone(this,cloner); | 98 completeClone(this,cloner); |
98 cloner = null; | 99 cloner = null; |
99 } | 100 } |
100 } | 101 } |
101 | 102 |
103 private void checkLuan(Luan luan) { | |
104 check(); | |
105 if( this.luan==null ) { | |
106 this.luan = luan; | |
107 } else if( this.luan != luan ) { | |
108 throw new RuntimeException("wrong luan"); | |
109 } | |
110 } | |
111 | |
102 private void completeClone(LuanTable clone,LuanCloner cloner) { | 112 private void completeClone(LuanTable clone,LuanCloner cloner) { |
103 clone.map = cloner.clone(map); | 113 clone.map = cloner.clone(map); |
104 clone.list = (List)cloner.clone(list); | 114 clone.list = (List)cloner.clone(list); |
105 clone.metatable = (LuanTable)cloner.clone(metatable); | 115 clone.metatable = (LuanTable)cloner.clone(metatable); |
106 clone.closure = (LuanClosure)cloner.clone(closure); | 116 clone.closure = (LuanClosure)cloner.clone(closure); |
117 clone.luan = (Luan)cloner.clone(luan); | |
107 } | 118 } |
108 | 119 |
109 @Override public void makeImmutable(LuanImmutabler immutabler) throws LuanException { | 120 @Override public void makeImmutable(LuanImmutabler immutabler) throws LuanException { |
110 check(); | 121 check(); |
111 immutabler.makeImmutable(map); | 122 immutabler.makeImmutable(map); |
131 public Map rawMap() { | 142 public Map rawMap() { |
132 check(); | 143 check(); |
133 return map!=null ? map : Collections.emptyMap(); | 144 return map!=null ? map : Collections.emptyMap(); |
134 } | 145 } |
135 | 146 |
136 public String toStringLuan() throws LuanException { | 147 public String toStringLuan(Luan luan) throws LuanException { |
137 Object h = getHandler("__to_string"); | 148 Object h = getHandler("__to_string"); |
138 if( h == null ) | 149 if( h == null ) |
139 return rawToString(); | 150 return rawToString(); |
140 LuanFunction fn = Luan.checkFunction(h); | 151 LuanFunction fn = Luan.checkFunction(h); |
141 return Luan.checkString( Luan.first( fn.call(this) ) ); | 152 return Luan.checkString( Luan.first( fn.call(luan,this) ) ); |
142 } | 153 } |
143 | 154 |
144 public String rawToString() { | 155 public String rawToString() { |
145 return "table: " + Integer.toHexString(hashCode()); | 156 return "table: " + Integer.toHexString(hashCode()); |
146 } | 157 } |
147 | 158 |
148 public Object get(Luan luan,Object key) throws LuanException { | 159 public Object get(Luan luan,Object key) throws LuanException { |
160 //checkLuan(luan); | |
149 Object value = rawGet(key); | 161 Object value = rawGet(key); |
150 if( value != null ) | 162 if( value != null ) |
151 return value; | 163 return value; |
152 Object h = getHandler("__index"); | 164 Object h = getHandler("__index"); |
153 if( h==null ) | 165 if( h==null ) |
154 return null; | 166 return null; |
155 if( h instanceof LuanFunction ) { | 167 if( h instanceof LuanFunction ) { |
156 LuanFunction fn = (LuanFunction)h; | 168 LuanFunction fn = (LuanFunction)h; |
157 return Luan.first(fn.call(this,key)); | 169 return Luan.first(fn.call(luan,this,key)); |
158 } | 170 } |
159 return luan.index(h,key); | 171 return luan.index(h,key); |
160 } | 172 } |
161 | 173 |
162 public Object rawGet(Object key) { | 174 public Object rawGet(Object key) { |
177 } | 189 } |
178 return map.get(key); | 190 return map.get(key); |
179 } | 191 } |
180 | 192 |
181 public void put(Luan luan,Object key,Object value) throws LuanException { | 193 public void put(Luan luan,Object key,Object value) throws LuanException { |
194 //checkLuan(luan); | |
182 Object h = getHandler("__new_index"); | 195 Object h = getHandler("__new_index"); |
183 if( h==null || rawGet(key)!=null ) { | 196 if( h==null || rawGet(key)!=null ) { |
184 rawPut(key,value); | 197 rawPut(key,value); |
185 return; | 198 return; |
186 } | 199 } |
187 if( h instanceof LuanFunction ) { | 200 if( h instanceof LuanFunction ) { |
188 LuanFunction fn = (LuanFunction)h; | 201 LuanFunction fn = (LuanFunction)h; |
189 fn.call(this,key,value); | 202 fn.call(luan,this,key,value); |
190 return; | 203 return; |
191 } | 204 } |
192 if( h instanceof LuanTable ) { | 205 if( h instanceof LuanTable ) { |
193 LuanTable tbl = (LuanTable)h; | 206 LuanTable tbl = (LuanTable)h; |
194 tbl.put(luan,key,value); | 207 tbl.put(luan,key,value); |
293 public void rawSort(Comparator<Object> cmp) { | 306 public void rawSort(Comparator<Object> cmp) { |
294 check(); | 307 check(); |
295 Collections.sort(list(),cmp); | 308 Collections.sort(list(),cmp); |
296 } | 309 } |
297 | 310 |
298 public int length() throws LuanException { | 311 public int length(Luan luan) throws LuanException { |
299 Object h = getHandler("__len"); | 312 Object h = getHandler("__len"); |
300 if( h != null ) { | 313 if( h != null ) { |
301 LuanFunction fn = Luan.checkFunction(h); | 314 LuanFunction fn = Luan.checkFunction(h); |
302 return (Integer)Luan.first(fn.call(this)); | 315 return (Integer)Luan.first(fn.call(luan,this)); |
303 } | 316 } |
304 return rawLength(); | 317 return rawLength(); |
305 } | 318 } |
306 | 319 |
307 public int rawLength() { | 320 public int rawLength() { |
308 check(); | 321 check(); |
309 return list==null ? 0 : list.size(); | 322 return list==null ? 0 : list.size(); |
310 } | 323 } |
311 | 324 |
312 public Iterable<Map.Entry> iterable() throws LuanException { | 325 public Iterable<Map.Entry> iterable(Luan luan) throws LuanException { |
313 final Iterator<Map.Entry> iter = iterator(); | 326 final Iterator<Map.Entry> iter = iterator(luan); |
314 return new Iterable<Map.Entry>() { | 327 return new Iterable<Map.Entry>() { |
315 public Iterator<Map.Entry> iterator() { | 328 public Iterator<Map.Entry> iterator() { |
316 return iter; | 329 return iter; |
317 } | 330 } |
318 }; | 331 }; |
325 return iter; | 338 return iter; |
326 } | 339 } |
327 }; | 340 }; |
328 } | 341 } |
329 | 342 |
330 public Iterator<Map.Entry> iterator() throws LuanException { | 343 public Iterator<Map.Entry> iterator(final Luan luan) throws LuanException { |
331 if( getHandler("__pairs") == null ) | 344 if( getHandler("__pairs") == null ) |
332 return rawIterator(); | 345 return rawIterator(); |
333 final LuanFunction fn = pairs(); | 346 final LuanFunction fn = pairs(luan); |
334 return new Iterator<Map.Entry>() { | 347 return new Iterator<Map.Entry>() { |
335 private Map.Entry<Object,Object> next = getNext(); | 348 private Map.Entry<Object,Object> next = getNext(); |
336 | 349 |
337 private Map.Entry<Object,Object> getNext() { | 350 private Map.Entry<Object,Object> getNext() { |
338 try { | 351 try { |
339 Object obj = fn.call(); | 352 Object obj = fn.call(luan); |
340 if( obj==null ) | 353 if( obj==null ) |
341 return null; | 354 return null; |
342 Object[] a = (Object[])obj; | 355 Object[] a = (Object[])obj; |
343 if( a.length == 0 || a[0]==null ) | 356 if( a.length == 0 || a[0]==null ) |
344 return null; | 357 return null; |
362 throw new UnsupportedOperationException(); | 375 throw new UnsupportedOperationException(); |
363 } | 376 } |
364 }; | 377 }; |
365 } | 378 } |
366 | 379 |
367 public LuanFunction pairs() throws LuanException { | 380 public LuanFunction pairs(Luan luan) throws LuanException { |
368 Object h = getHandler("__pairs"); | 381 Object h = getHandler("__pairs"); |
369 if( h != null ) { | 382 if( h != null ) { |
370 if( h instanceof LuanFunction ) { | 383 if( h instanceof LuanFunction ) { |
371 LuanFunction fn = (LuanFunction)h; | 384 LuanFunction fn = (LuanFunction)h; |
372 Object obj = Luan.first(fn.call(this)); | 385 Object obj = Luan.first(fn.call(luan,this)); |
373 if( !(obj instanceof LuanFunction) ) | 386 if( !(obj instanceof LuanFunction) ) |
374 throw new LuanException( "metamethod __pairs should return function but returned " + Luan.type(obj) ); | 387 throw new LuanException( "metamethod __pairs should return function but returned " + Luan.type(obj) ); |
375 return (LuanFunction)obj; | 388 return (LuanFunction)obj; |
376 } | 389 } |
377 throw new LuanException( "invalid type of metamethod __pairs: " + Luan.type(h) ); | 390 throw new LuanException( "invalid type of metamethod __pairs: " + Luan.type(h) ); |
378 } | 391 } |
379 return rawPairs(); | 392 return rawPairs(); |
380 } | 393 } |
381 | 394 |
382 private LuanFunction rawPairs() { | 395 private LuanFunction rawPairs() { |
383 return new LuanFunction(false) { // ??? | 396 return new LuanFunction() { |
384 final Iterator<Map.Entry> iter = rawIterator(); | 397 final Iterator<Map.Entry> iter = rawIterator(); |
385 | 398 |
386 @Override public Object[] call(Object[] args) { | 399 @Override public Object[] call(Luan luan,Object[] args) { |
387 if( !iter.hasNext() ) | 400 if( !iter.hasNext() ) |
388 return LuanFunction.NOTHING; | 401 return LuanFunction.NOTHING; |
389 Map.Entry<Object,Object> entry = iter.next(); | 402 Map.Entry<Object,Object> entry = iter.next(); |
390 return new Object[]{entry.getKey(),entry.getValue()}; | 403 return new Object[]{entry.getKey(),entry.getValue()}; |
391 } | 404 } |
471 private static Map<Object,Object> newMap() { | 484 private static Map<Object,Object> newMap() { |
472 return new LinkedHashMap<Object,Object>(); | 485 return new LinkedHashMap<Object,Object>(); |
473 } | 486 } |
474 | 487 |
475 public boolean isSet() throws LuanException { | 488 public boolean isSet() throws LuanException { |
476 for( Map.Entry<Object,Object> entry : iterable() ) { | 489 for( Map.Entry<Object,Object> entry : rawIterable() ) { |
477 if( !entry.getValue().equals(Boolean.TRUE) ) | 490 if( !entry.getValue().equals(Boolean.TRUE) ) |
478 return false; | 491 return false; |
479 } | 492 } |
480 return true; | 493 return true; |
481 } | 494 } |
482 | 495 |
483 public Set<Object> asSet() throws LuanException { | 496 public Set<Object> asSet() throws LuanException { |
484 Set<Object> set = new HashSet<Object>(); | 497 Set<Object> set = new HashSet<Object>(); |
485 for( Map.Entry<Object,Object> entry : iterable() ) { | 498 for( Map.Entry<Object,Object> entry : rawIterable() ) { |
486 set.add(entry.getKey()); | 499 set.add(entry.getKey()); |
487 } | 500 } |
488 return set; | 501 return set; |
489 } | 502 } |
490 | 503 |
491 public Map<Object,Object> asMap() throws LuanException { | 504 public Map<Object,Object> asMap() throws LuanException { |
492 Map<Object,Object> map = newMap(); | 505 Map<Object,Object> map = newMap(); |
493 for( Map.Entry<Object,Object> entry : iterable() ) { | 506 for( Map.Entry<Object,Object> entry : rawIterable() ) { |
494 map.put(entry.getKey(),entry.getValue()); | 507 map.put(entry.getKey(),entry.getValue()); |
495 } | 508 } |
496 return map; | 509 return map; |
497 } | 510 } |
498 | 511 |
534 | 547 |
535 protected void finalize() throws Throwable { | 548 protected void finalize() throws Throwable { |
536 Object h = getHandler("__gc"); | 549 Object h = getHandler("__gc"); |
537 if( h != null ) { | 550 if( h != null ) { |
538 LuanFunction fn = Luan.checkFunction(h); | 551 LuanFunction fn = Luan.checkFunction(h); |
539 fn.call(this); | 552 fn.call(new Luan(),this); // ??? should be immutable |
540 } | 553 } |
541 super.finalize(); | 554 super.finalize(); |
542 } | 555 } |
543 | 556 |
544 public LuanFunction fn(Luan luan,String fnName) throws LuanException { | 557 public LuanFunction fn(String fnName) throws LuanException { |
545 return (LuanFunction)get(luan,fnName); | 558 return (LuanFunction)rawGet(fnName); |
546 } | 559 } |
547 | 560 |
548 public static void debug(LuanTable table) { | 561 public static void debug(LuanTable table) { |
549 System.out.println("isMap "+table.isMap()); | 562 System.out.println("isMap "+table.isMap()); |
550 } | 563 } |