Example #1
0
        /// <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); }
        }
Example #2
0
        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());
            }
        }
Example #3
0
        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));
        }
Example #4
0
 /// <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));
 }
Example #5
0
 /// <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;
 }
Example #6
0
 /// <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)
 {
 }
Example #7
0
 private bool sameType(ErlTypeOrder tp1, ErlTypeOrder tp2)
 {
     return(tp1 == tp2 ||
            tp1 == ErlTypeOrder.ErlLong && tp2 == ErlTypeOrder.ErlByte ||
            tp1 == ErlTypeOrder.ErlByte && tp2 == ErlTypeOrder.ErlLong);
 }
Example #8
0
 /// <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;
 }
Example #9
0
 /// <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) {}