static object ReadRecord(object form, Symbol recordName, object opts, object pendingForms)
{
bool readeval = RT.booleanCast(RT.ReadEvalVar.deref());
if (!readeval)
throw new InvalidOperationException("Record construction syntax can only be used when *read-eval* == true ");
Type recordType = RT.classForNameE(recordName.ToString());
IPersistentVector recordEntries;
IPersistentMap vals;
object ret = null;
ConstructorInfo[] allCtors = recordType.GetConstructors();
if ((recordEntries = form as IPersistentVector) != null)
{
// shortForm
bool ctorFound = false;
foreach (ConstructorInfo cinfo in allCtors)
if (cinfo.GetParameters().Length == recordEntries.count())
ctorFound = true;
if (!ctorFound)
throw new ArgumentException(String.Format("Unexpected number of constructor arguments to {0}: got {1}", recordType.ToString(), recordEntries.count()));
ret = Reflector.InvokeConstructor(recordType, RT.toArray(recordEntries));
}
else if ((vals = form as IPersistentMap) != null)
{
for (ISeq s = RT.keys(vals); s != null; s = s.next())
{
if (!(s.first() is Keyword))
throw new ArgumentException(String.Format("Unreadable defrecord form: key must be of type clojure.lang.Keyword, got {0}", s.first().ToString()));
}
ret = Reflector.InvokeStaticMethod(recordType, "create", new Object[] { vals });
}
else
{
throw new ArgumentException("Unreadable constructor form starting with \"#" + recordName + "\"");
}
return ret;
}