public static ErlangValue PlusPlus(ErlangValue list, ErlangValue tail) { if (list.Kind != ErlangValueKind.List) { return(new ErlangError("not a list")); } return(ErlangList.CloneWithTail((ErlangList)list, tail)); }
public ErlangNativeModule(object target) { // get name var methodAttribute = target.GetType().GetTypeInfo().GetCustomAttributes(typeof(ErlangModuleAttribute), false).OfType <ErlangModuleAttribute>().Single(); Name = methodAttribute.Name; functionMap = new Dictionary <Tuple <string, int>, MethodInfo>(); Target = target; foreach (var methodInfo in Target.GetType().GetTypeInfo().DeclaredMethods) { var parameters = methodInfo.GetParameters(); var methodAttrs = methodInfo.GetCustomAttributes(typeof(ErlangFunctionAttribute), false).OfType <ErlangFunctionAttribute>().ToArray(); if (parameters.All(p => p.ParameterType == typeof(ErlangValue)) && methodInfo.ReturnType == typeof(ErlangValue) && methodAttrs.Length == 1) { functionMap.Add(Tuple.Create(methodAttrs[0].Name, parameters.Length), methodInfo); } } AllFunctions = new ErlangList(functionMap.Keys .Select(f => new ErlangTuple(new ErlangAtom(f.Item1), new ErlangNumber(f.Item2))) .Concat(new ErlangTuple[] { new ErlangTuple(new ErlangAtom("module_info"), new ErlangNumber(0)), new ErlangTuple(new ErlangAtom("module_info"), new ErlangNumber(1)) }) .ToArray()); ModuleInfo = new ErlangList( new ErlangTuple( new ErlangAtom("exports"), AllFunctions ), new ErlangTuple( new ErlangAtom("imports"), new ErlangList() // an empty list. may go away in the future ), new ErlangTuple( new ErlangAtom("attributes"), new ErlangList() // TODO: populate attributes ), new ErlangTuple( new ErlangAtom("compile"), new ErlangList() // TODO: populate compile options ) ); }
public override ErlangValue Evaluate(ErlangProcess process) { var values = new ErlangValue[Elements.Length]; for (int i = 0; i < Elements.Length; i++) { var value = Elements[i].Evaluate(process); if (value.Kind == ErlangValueKind.Error) { return(value); } values[i] = value; } var list = new ErlangList(values, Tail == null ? null : Tail.Evaluate(process)); return(list); }
private ErlangList(ErlangValue[] values, int index, ErlangValue tail) { if (values != null && index < values.Length) { Value = values[index]; if (index == values.Length - 1) { Tail = tail ?? new ErlangList(); } else { Tail = new ErlangList(values, index + 1, tail); } var tailLength = Tail.Kind == ErlangValueKind.List ? ((ErlangList)Tail).Length : -1; Length = tailLength < 0 ? -1 : tailLength + 1; } }
internal static ErlangValue CloneWithTail(ErlangList list, ErlangValue tail) { if (IsEmptyList(list.Tail)) { return(new ErlangList(list.Value, tail)); } else if (list.Tail != null && list.Tail.Kind != ErlangValueKind.List) { return(new ErlangError("can't concat")); } else { var newTail = CloneWithTail((ErlangList)list.Tail, tail); if (newTail.Kind == ErlangValueKind.Error) { return(newTail); } return(new ErlangList(list.Value, newTail)); } }