/// <summary> /// Try to convert .NET native object type to corresponding Erlang term of given type. /// Throw exception if conversion is not possible /// </summary> public static IErlObject ToErlObject(this object o, ErlTypeOrder etp, bool strict = true) { if (o == null) { return(ErlAtom.Undefined); } var t = o.GetType(); if (t.IsValueType || o is string) { return(coreToErlObject(o, etp, strict)); } if (ts_Refs == null) { ts_Refs = new HashSet <object>(NFX.ReferenceEqualityComparer <object> .Instance); } if (ts_Refs.Contains(o)) { throw new ErlException(StringConsts.ERL_CANNOT_CONVERT_TYPES_CYCLE_ERROR, o.GetType().FullName, typeof(IErlObject).Name); } try { return(coreToErlObject(o, etp, strict)); } finally { ts_Refs.Remove(o); } }
private static IErlObject coreToErlObject(object o, ErlTypeOrder etp, bool strict) { var eh = strict ? ConvertErrorHandling.Throw : ConvertErrorHandling.ReturnDefault; var e = o as IErlObject; if (e != null) { return(e); } try { switch (etp) { case ErlTypeOrder.ErlObject: case ErlTypeOrder.ErlAtom: return(new ErlAtom(o.ToString())); case ErlTypeOrder.ErlBinary: return(new ErlBinary((byte[])o)); case ErlTypeOrder.ErlBoolean: return(new ErlBoolean(o.AsBool(handling: eh))); case ErlTypeOrder.ErlByte: return(new ErlByte(o.AsByte(handling: eh))); case ErlTypeOrder.ErlDouble: return(new ErlDouble(o.AsDouble(handling: eh))); case ErlTypeOrder.ErlLong: return(new ErlLong(o.AsLong(handling: eh))); case ErlTypeOrder.ErlList: { var list = new ErlList(); foreach (var item in (IEnumerable)o) { list.Add(item.ToErlObject()); } return(list); } case ErlTypeOrder.ErlString: return(new ErlString(o.AsString(handling: eh))); case ErlTypeOrder.ErlTuple: return(new ErlTuple((object[])o)); case ErlTypeOrder.ErlPid: case ErlTypeOrder.ErlPort: case ErlTypeOrder.ErlRef: case ErlTypeOrder.ErlVar: default: throw new Exception(); } } catch (Exception) { throw new ErlException (StringConsts.ERL_CANNOT_CONVERT_TYPES_ERROR, o.GetType().ToString(), etp.ToString()); } }
private static ErlVar pVariable(string fmt, ref int pos) { int start = pos; for (pos = skipWSAndComments(fmt, pos); pos < fmt.Length; pos++) { char c = fmt[pos]; if (char.IsLetterOrDigit(c) || (c == '_')) { continue; } break; } ErlTypeOrder type = ErlTypeOrder.ErlObject; int i = pos; int end = pos; // TODO: Add recursive type checking (i.e. A :: [{atom(), [integer() | string() | double() | tuple()]}]) if (fmt.Length > i + 1 && fmt[i] == ':' && fmt[i + 1] == ':') { i = pos + 2; int tps = i; for (char c = fmt[i]; char.IsLetter(c) && i < fmt.Length - 1; c = fmt[++i]) { ; } if (fmt[i] == '(' && i < fmt.Length - 1 && fmt[i + 1] == ')') { pos = i + 2; string tp = fmt.Substring(tps, i - tps); switch (tp) { case "int": case "long": case "integer": type = ErlTypeOrder.ErlLong; break; case "str": case "string": type = ErlTypeOrder.ErlString; break; case "atom": type = ErlTypeOrder.ErlAtom; break; case "float": case "double": type = ErlTypeOrder.ErlDouble; break; case "binary": type = ErlTypeOrder.ErlBinary; break; case "bool": case "boolean": type = ErlTypeOrder.ErlBoolean; break; case "byte": type = ErlTypeOrder.ErlByte; break; case "char": type = ErlTypeOrder.ErlByte; break; case "list": type = ErlTypeOrder.ErlList; break; case "tuple": type = ErlTypeOrder.ErlTuple; break; case "pid": type = ErlTypeOrder.ErlPid; break; case "ref": case "reference": type = ErlTypeOrder.ErlRef; break; case "port": type = ErlTypeOrder.ErlPort; break; default: throw new ErlException(StringConsts.ERL_UNSUPPORTED_TERM_TYPE_ERROR, tp); } } else { throw new ErlException(StringConsts.ERL_INVALID_VARIABLE_TYPE_ERROR, fmt.Substring(start, pos - start)); } } else { type = ErlTypeOrder.ErlObject; } int len = end - start; return(new ErlVar(fmt.Substring(start, len), type)); }
/// <summary> /// Add a variable binding associating value with variable name /// </summary> /// <param name="name">Name of the variable</param> /// <param name="et">Erlang type to use for conversion of the given CLR type</param> /// <param name="o">Value to associate with name</param> public void Add(ErlAtom name, ErlTypeOrder et, object o) { Add(name, o.ToErlObject(et)); }
/// <summary> /// Create an Erlang typed named variable using ErlAtom as name /// </summary> /// <param name="name">Variable name</param> /// <param name="type">Value type</param> public ErlVar(ErlAtom name, ErlTypeOrder type = ErlTypeOrder.ErlObject) { m_Name = name; ValueType = type; }
/// <summary> /// Create an Erlang typed named variable /// </summary> /// <param name="name">Variable name</param> /// <param name="type">Value type</param> public ErlVar(string name, ErlTypeOrder type) : this(name == null ? ConstAtoms.ANY : new ErlAtom(name), type) { }
private bool sameType(ErlTypeOrder tp1, ErlTypeOrder tp2) { return(tp1 == tp2 || tp1 == ErlTypeOrder.ErlLong && tp2 == ErlTypeOrder.ErlByte || tp1 == ErlTypeOrder.ErlByte && tp2 == ErlTypeOrder.ErlLong); }
/// <summary> /// Create an Erlang typed named variable /// </summary> /// <param name="name">Variable name</param> /// <param name="type">Value type</param> public ErlVar(string name, ErlTypeOrder type) : this(name == null ? ConstAtoms.ANY : new ErlAtom(name), type) {}