예제 #1
0
            protected override object Read(PushbackTextReader r, char caret, object opts)
            {
                int startLine = -1;
                int startCol  = -1;
                LineNumberingTextReader lntr = r as LineNumberingTextReader;

                if (lntr != null)
                {
                    startLine = lntr.LineNumber;
                    startCol  = lntr.ColumnNumber;
                }

                IPersistentMap metaAsMap;
                {
                    object meta = ReadAux(r, opts);

                    if (meta is Symbol || meta is String)
                    {
                        metaAsMap = RT.map(RT.TagKey, meta);
                    }
                    else if (meta is Keyword)
                    {
                        metaAsMap = RT.map(meta, true);
                    }
                    else if ((metaAsMap = meta as IPersistentMap) == null)
                    {
                        throw new ArgumentException("Metadata must be Symbol,Keyword,String or Map");
                    }
                }

                object o = ReadAux(r, opts);

                if (o is IMeta)
                {
                    if (startLine != -1 && o is ISeq)
                    {
                        metaAsMap = metaAsMap.assoc(RT.LineKey, startLine)
                                    .assoc(RT.ColumnKey, startCol)
                                    .assoc(RT.SourceSpanKey, RT.map(
                                               RT.StartLineKey, startLine,
                                               RT.StartColumnKey, startCol,
                                               RT.EndLineKey, lntr.LineNumber,
                                               RT.EndColumnKey, lntr.ColumnNumber));
                    }

                    IReference iref = o as IReference;
                    if (iref != null)
                    {
                        iref.resetMeta(metaAsMap);
                        return(o);
                    }
                    object ometa = RT.meta(o);
                    for (ISeq s = RT.seq(metaAsMap); s != null; s = s.next())
                    {
                        IMapEntry kv = (IMapEntry)s.first();
                        ometa = RT.assoc(ometa, kv.key(), kv.val());
                    }
                    return(((IObj)o).withMeta((IPersistentMap)ometa));
                }
                else
                {
                    throw new ArgumentException("Metadata can only be applied to IMetas");
                }
            }