Permalink
Browse files

Finally sort out the issue with recursive objects

  • Loading branch information...
1 parent c042e82 commit f47b369c85fbcf1d8b1fa0ebe26ece4fa62f8df2 @olabini committed Jul 21, 2009
@@ -73,7 +73,7 @@ public boolean basicLoad(final Ruby runtime) throws IOException {
cYObject.addReadWriteAttribute(ctx, "class");
cYObject.addReadWriteAttribute(ctx, "ivars");
- RubyClass cBadAlias = rb_yecht.defineClassUnder("BadAlias", runtime.getObject(), runtime.getObject().getAllocator());
+ RubyClass cBadAlias = rb_yecht.defineClassUnder("BadAlias", runtime.getObject(), YechtYAML.BadAlias.Allocator);
cBadAlias.defineAnnotatedMethods(YechtYAML.BadAlias.class);
cBadAlias.addReadWriteAttribute(ctx, "name");
cBadAlias.includeModule(runtime.getComparable());
@@ -44,6 +44,85 @@
import org.jruby.util.TypeConverter;
public class YechtYAML {
+ private static interface PossibleLinkNode {
+ void addLink(StorageLink link);
+ void replaceLinks(IRubyObject newObject);
+ }
+
+ private static abstract class StorageLink {
+ public abstract void replaceLinkWith(IRubyObject object);
+ }
+
+ private static class ArrayStorageLink extends StorageLink {
+ private final RubyArray array;
+ private final int index;
+ private final IRubyObject originalObject;
+
+ public ArrayStorageLink(IRubyObject arr, int index, IRubyObject originalObject) {
+ this.array = (RubyArray)arr;
+ this.index = index;
+ this.originalObject = originalObject;
+ }
+
+ public void replaceLinkWith(IRubyObject newObject) {
+ array.store(index, newObject);
+ }
+ }
+
+ private static class HashStorageLink extends StorageLink {
+ private final RubyHash hash;
+ private final IRubyObject key;
+ private final IRubyObject originalObject;
+
+ public HashStorageLink(IRubyObject h, IRubyObject key, IRubyObject originalObject) {
+ this.hash = (RubyHash)h;
+ this.key = key;
+ this.originalObject = originalObject;
+ }
+
+ public void replaceLinkWith(IRubyObject newObject) {
+ hash.fastASet(key, newObject);
+ }
+ }
+
+ public static class BadAlias extends RubyObject implements PossibleLinkNode {
+ public static final ObjectAllocator Allocator = new ObjectAllocator() {
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
+ return new BadAlias(runtime, klass);
+ }
+ };
+
+ public BadAlias(Ruby runtime, RubyClass metaClass) {
+ super(runtime, metaClass);
+ }
+
+ private List<StorageLink> links = new LinkedList<StorageLink>();
+ public void addLink(StorageLink link) {
+ links.add(link);
+ }
+
+ public void replaceLinks(IRubyObject newObject) {
+ for(StorageLink sl : links) {
+ sl.replaceLinkWith(newObject);
+ }
+ }
+
+ // syck_badalias_initialize
+ @JRubyMethod
+ public static IRubyObject initialize(IRubyObject self, IRubyObject val) {
+ self.getInstanceVariables().setInstanceVariable("@name", val);
+ return self;
+ }
+
+ // syck_badalias_cmp
+ @JRubyMethod(name = "<=>")
+ public static IRubyObject cmp(IRubyObject alias1, IRubyObject alias2) {
+ IRubyObject str1 = alias1.getInstanceVariables().getInstanceVariable("@name");
+ IRubyObject str2 = alias2.getInstanceVariables().getInstanceVariable("@name");
+ return str1.callMethod(alias1.getRuntime().getCurrentContext(), "<=>", str2);
+ }
+ }
+
public static class RubyIoStrRead implements IoStrRead {
private IRubyObject port;
public RubyIoStrRead(IRubyObject port) {
@@ -307,6 +386,9 @@ public static boolean orgHandler(IRubyObject self, org.yecht.Node n, IRubyObject
obj = RubyArray.newArray(runtime, dl.idx);
for(int i = 0; i < dl.idx; i++) {
IRubyObject _obj = (IRubyObject)n.seqRead(i);
+ if(_obj instanceof PossibleLinkNode) {
+ ((PossibleLinkNode)_obj).addLink(new ArrayStorageLink(obj, i, _obj));
+ }
((RubyArray)obj).store(i, _obj);
}
break;
@@ -365,6 +447,9 @@ public IRubyObject call(ThreadContext _ctx, IRubyObject[] largs, Block blk) {
}
if(!skip_aset) {
+ if(v instanceof PossibleLinkNode) {
+ ((PossibleLinkNode)v).addLink(new HashStorageLink(obj, k, v));
+ }
((RubyHash)obj).fastASet(k, v);
}
}
@@ -386,6 +471,12 @@ public RubyLoadHandler(Ruby runtime) {
// rb_syck_load_handler
public Object handle(Parser p, org.yecht.Node n) {
+// System.err.println("load_handler for node: " + n.type_id + " with anchor: " + n.anchor);
+// System.err.println(" id: " + n.id);
+// if(n.id != null) {
+// System.err.println(" val: " + ((IRubyObject)n.id).inspect().toString());
+// }
+
// System.err.println("rb_syck_load_handler(" + n + ")");
YParser.Extra bonus = (YParser.Extra)p.bonus;
IRubyObject resolver = bonus.resolver;
@@ -397,7 +488,10 @@ public Object handle(Parser p, org.yecht.Node n) {
IRubyObject obj = resolver.callMethod(runtime.getCurrentContext(), "node_import", _n);
// System.err.println(" node_import -> " + obj);
- if(n.id == null || !obj.isNil()) {
+ if(n.id != null && !obj.isNil()) {
+ if(n.id instanceof PossibleLinkNode) {
+ ((PossibleLinkNode)n.id).replaceLinks(obj);
+ }
n.id = obj;
// System.err.println(" -- LoadHandler, setting id, yay!");
}
@@ -413,7 +507,7 @@ public Object handle(Parser p, org.yecht.Node n) {
((RubyHash)bonus.data).fastASet(((RubyHash)bonus.data).rb_size(), obj);
// System.err.println(" -> rb_syck_load_handler=" + n.id);
- return n.id;
+ return obj;
}
}
@@ -456,7 +550,7 @@ public RubyBadAnchorHandler(Ruby runtime) {
IRubyObject anchor_name = runtime.newString(a);
IRubyObject nm = runtime.newString("name");
org.yecht.Node badanc = org.yecht.Node.newMap(nm, anchor_name);
- badanc.type_id = "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias";
+ badanc.type_id = "tag:ruby.yaml.org,2002:object:YAML::Yecht::BadAlias";
return badanc;
}
}
@@ -1354,23 +1448,6 @@ public static IRubyObject yaml_initialize(IRubyObject self, IRubyObject klass, I
}
}
- public static class BadAlias {
- // syck_badalias_initialize
- @JRubyMethod
- public static IRubyObject initialize(IRubyObject self, IRubyObject val) {
- self.getInstanceVariables().setInstanceVariable("@name", val);
- return self;
- }
-
- // syck_badalias_cmp
- @JRubyMethod(name = "<=>")
- public static IRubyObject cmp(IRubyObject alias1, IRubyObject alias2) {
- IRubyObject str1 = alias1.getInstanceVariables().getInstanceVariable("@name");
- IRubyObject str2 = alias2.getInstanceVariables().getInstanceVariable("@name");
- return str1.callMethod(alias1.getRuntime().getCurrentContext(), "<=>", str2);
- }
- }
-
// syck_out_mark
public static void outMark(IRubyObject emitter, IRubyObject node) {
Emitter emitterPtr = (Emitter)emitter.dataGetStructChecked();
@@ -1,4 +1,4 @@
-/* Generated by re2j 0.13.6.dev on Mon Jul 20 16:45:09 2009 */
+/* Generated by re2j 0.13.6.dev on Tue Jul 21 13:26:28 2009 */
package org.yecht;
import java.io.IOException;
@@ -1,4 +1,4 @@
-/* Generated by re2j 0.13.6.dev on Mon Jul 20 16:45:09 2009 */
+/* Generated by re2j 0.13.6.dev on Tue Jul 21 13:26:28 2009 */
package org.yecht;
// Equivalent to implicit.re
@@ -15,16 +15,22 @@
public Data data;
public Object shortcut;
+ Node() {
+ }
+
public String toString() {
- switch(kind) {
- case Str:
- return "Str[id=" + id +", type=" + type_id +", val="+data+"]";
- case Seq:
- return "Seq[id=" + id +", type=" + type_id +", val="+data+"]";
- case Map:
- return "Map[id=" + id +", type=" + type_id +", val="+data+"]";
+ if(kind != null) {
+ switch(kind) {
+ case Str:
+ return "Str[id=" + id +", type=" + type_id +", val="+data+"]";
+ case Seq:
+ return "Seq[id=" + id +", type=" + type_id +", val="+data+"]";
+ case Map:
+ return "Map[id=" + id +", type=" + type_id +", val="+data+"]";
+ }
}
- return "other";
+
+ return "other[id=" + id +", type=" + type_id +", val="+data+"]";
}
// syck_replace_str
@@ -28,7 +28,7 @@ private Parser() {}
int force_token;
public boolean eof;
JechtIO io;
- Map<String, Node> anchors, bad_anchors;
+ Map<String, Node> anchors, bad_anchors, prepared_anchors;
// Map<Integer, Object> syms;
Level[] levels;
int lvl_idx;
@@ -97,6 +97,7 @@ public static Parser newParser() {
// p.syms = new HashMap<Integer, Object>();
p.anchors = null;
p.bad_anchors = null;
+ p.prepared_anchors = null;
p.implicit_typing = true;
p.taguri_expansion = false;
p.bufsize = YAML.BUFFERSIZE;
@@ -297,21 +298,37 @@ public Object addNode(Node n) {
return n.id;
}
+// public void prepareAnchor(String a, Node n) {
+// System.err.println("prepareAnchor(" + a + ", " + n + ")");
+// if(prepared_anchors == null) {
+// prepared_anchors = new HashMap<String, Node>();
+// }
+// prepared_anchors.put(a, n);
+// }
+
// syck_hdlr_add_anchor
public Node addAnchor(String a, Node n) {
+// System.err.println("addAnchor(" + a + ", " + n + ")");
+
n.anchor = a;
if(bad_anchors != null) {
+// System.err.print(" -- bad_anchors != null\n");
if(bad_anchors.containsKey(a)) {
+// System.err.print(" -- st_lookup(p->bad_anchors) succeeded\n");
if(n.kind != KindTag.Str) {
Node bad = bad_anchors.get(a);
+// System.err.print(" -- this is not a str\n");
+// System.err.print(" -- id: " + n.id + ", bad.id: " + bad.id +"\n");
n.id = bad.id;
handler.handle(this, n);
}
}
}
if(anchors == null) {
+// System.err.print(" -- anchors == null\n");
anchors = new HashMap<String, Node>();
}
+// System.err.print(" -- inserting into the anchor again\n");
anchors.put(a, n);
return n;
}
@@ -326,25 +343,37 @@ public void removeAnchor(String a) {
// syck_hdlr_get_anchor
public Node getAnchor(String a) {
+// System.err.println("getAnchor(" + a + ")");
Node n = null;
if(anchors != null) {
+// System.err.print(" -- anchors != null\n");
if(anchors.containsKey(a)) {
+// System.err.print(" -- st_lookup succeeded\n");
n = anchors.get(a);
if(n != null) {
+// System.err.print(" -- n != 1\n");
return n;
} else {
+// System.err.print(" -- n === 1\n");
if(bad_anchors == null) {
+// System.err.print(" -- creating new list of bad anchors\n");
bad_anchors = new HashMap<String, Node>();
}
+// System.err.print(" -- checking if n exists in bad anchors\n");
if(!bad_anchors.containsKey(a)) {
+// System.err.print(" -- no, it doesnt\n");
n = bad_anchor_handler.handle(this, a);
bad_anchors.put(a, n);
+ } else {
+ n = bad_anchors.get(a);
}
}
}
}
+// System.err.print(" -- n == null?\n");
if(n == null) {
+// System.err.print(" --- yep ?\n");
n = bad_anchor_handler.handle(this, a);
}
@@ -1,4 +1,4 @@
-/* Generated by re2j 0.13.6.dev on Mon Jul 20 16:45:09 2009 */
+/* Generated by re2j 0.13.6.dev on Tue Jul 21 13:26:28 2009 */
package org.yecht;
import java.io.IOException;
@@ -267,7 +267,7 @@ inline_seq : '[' in_inline_seq ']'
in_inline_seq : inline_seq_atom
{
- $$ = Node.newSeq( parser.addNode((Node)$1));
+ $$ = Node.newSeq(parser.addNode((Node)$1));
}
| in_inline_seq ',' inline_seq_atom
{
@@ -335,28 +335,12 @@ complex_key : word_rep
complex_value : atom_or_empty
;
-/* Default needs to be added to SyckSeq i think...
- | '=' ':' atom
- {
- result = [ :DEFAULT, val[2] ]
- }
-*/
-
complex_mapping : complex_key ':' complex_value
{
$$ = Node.newMap(
parser.addNode( (Node)$1 ),
parser.addNode( (Node)$3 ) );
}
-/*
- | '?' atom
- {
- NULL_NODE( parser, n );
- $$ = syck_new_map(
- syck_hdlr_add_node( (SyckParser *)parser, $2 ),
- syck_hdlr_add_node( (SyckParser *)parser, n ) );
- }
-*/
;
in_implicit_map : complex_mapping
@@ -420,7 +404,7 @@ inline_map_atom : atom
Node n = NULL_NODE( parser );
$$ = Node.newMap(
parser.addNode( (Node)$1 ),
- parser.addNode( n ) );
+ parser.addNode( n ));
}
| basic_mapping
;
@@ -1,4 +1,4 @@
-// Output created by jacc on Mon Jul 20 16:45:10 CEST 2009
+// Output created by jacc on Tue Jul 21 13:26:29 CEST 2009
package org.yecht;
Oops, something went wrong.

0 comments on commit f47b369

Please sign in to comment.