comparison core/src/luan/LuanTable.java @ 419:8fbb961aabd5

improve repr() to check metamethod recursively
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 30 Apr 2015 23:15:40 -0600
parents d2ab2240cc65
children af82b266fe89
comparison
equal deleted inserted replaced
418:455784e2227d 419:8fbb961aabd5
279 279
280 public void setMetatable(LuanTable metatable) { 280 public void setMetatable(LuanTable metatable) {
281 this.metatable = metatable; 281 this.metatable = metatable;
282 } 282 }
283 283
284 public Object getHandler(String op) {
285 LuanTable t = getMetatable();
286 return t==null ? null : t.get(op);
287 }
288
284 public boolean hasJava() { 289 public boolean hasJava() {
285 return hasJava; 290 return hasJava;
286 } 291 }
287 292
288 public void setJava() { 293 public void setJava() {
326 331
327 public LuanTable cloneTable() { 332 public LuanTable cloneTable() {
328 return isList() ? new LuanTable(new ArrayList<Object>(asList())) : new LuanTable(asMap()); 333 return isList() ? new LuanTable(new ArrayList<Object>(asList())) : new LuanTable(asMap());
329 } 334 }
330 335
331 @Override public String repr() { 336 @Override public String repr(LuanState luan) throws LuanException {
332 return repr( Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) ); 337 LuanFunction fn = luan.JAVA.getHandlerFunction("__repr",this);
333 } 338 if( fn != null )
334 339 return luan.JAVA.checkString( Luan.first( luan.call(fn,"__repr",new Object[]{this}) ) );
335 private String repr(Set<LuanTable> set) { 340 return repr( luan, Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) );
341 }
342
343 private String repr(LuanState luan,Set<LuanTable> set) throws LuanException {
336 if( !set.add(this) ) { 344 if( !set.add(this) ) {
337 return "\"<circular reference>\""; 345 return "\"<circular reference>\"";
338 } 346 }
339 StringBuilder sb = new StringBuilder(); 347 StringBuilder sb = new StringBuilder();
340 sb.append('{'); 348 sb.append('{');
343 if( isFirst ) { 351 if( isFirst ) {
344 isFirst = false; 352 isFirst = false;
345 } else { 353 } else {
346 sb.append(", "); 354 sb.append(", ");
347 } 355 }
348 sb.append(repr(set,obj)); 356 sb.append(repr(luan,set,obj));
349 } 357 }
350 for( Map.Entry<Object,Object> entry : map().entrySet() ) { 358 for( Map.Entry<Object,Object> entry : map().entrySet() ) {
351 if( isFirst ) { 359 if( isFirst ) {
352 isFirst = false; 360 isFirst = false;
353 } else { 361 } else {
354 sb.append(", "); 362 sb.append(", ");
355 } 363 }
356 sb.append(reprKey(set,entry.getKey())).append('=').append(repr(set,entry.getValue())); 364 sb.append(reprKey(luan,set,entry.getKey())).append('=').append(repr(luan,set,entry.getValue()));
357 } 365 }
358 sb.append('}'); 366 sb.append('}');
359 return sb.toString(); 367 return sb.toString();
360 } 368 }
361 369
362 private static final Pattern namePtn = Pattern.compile("[a-zA-Z_][a-zA-Z_0-9]*"); 370 private static final Pattern namePtn = Pattern.compile("[a-zA-Z_][a-zA-Z_0-9]*");
363 371
364 private String reprKey(Set<LuanTable> set,Object obj) { 372 private String reprKey(LuanState luan,Set<LuanTable> set,Object obj) throws LuanException {
365 if( obj instanceof String ) { 373 if( obj instanceof String ) {
366 String s = (String)obj; 374 String s = (String)obj;
367 if( namePtn.matcher(s).matches() ) 375 if( namePtn.matcher(s).matches() )
368 return s; 376 return s;
369 } 377 }
370 return "[" + repr(set,obj) + "]"; 378 return "[" + repr(luan,set,obj) + "]";
371 } 379 }
372 380
373 private String repr(Set<LuanTable> set,Object obj) { 381 private String repr(LuanState luan,Set<LuanTable> set,Object obj) throws LuanException {
374 if( obj instanceof LuanTable ) { 382 if( obj instanceof LuanTable ) {
375 LuanTable t = (LuanTable)obj; 383 LuanTable t = (LuanTable)obj;
376 return t.repr(set); 384 return t.repr(luan,set);
377 } else { 385 } else {
378 String s = Luan.repr(obj); 386 String s = luan.repr(obj);
379 if( s == null ) 387 if( s == null )
380 s = "<couldn't repr: " + Luan.stringEncode(Luan.toString(obj)) + ">"; 388 s = "<couldn't repr: " + Luan.stringEncode(Luan.toString(obj)) + ">";
381 return s; 389 return s;
382 } 390 }
383 } 391 }