示例#1
0
        public override HassiumObject Invoke(VirtualMachine vm, SourceLocation location, params HassiumObject[] args)
        {
            var a = Target.Method.GetCustomAttributes(typeof(FunctionAttribute), false);

            if (ParameterLengths.Length == 0)
            {
                ParameterLengths = new int[] { -1 }
            }
            ;

            if (a.Length > 0)
            {
                var reps = (a[0] as FunctionAttribute).SourceRepresentations;
                if (reps.Count > 1 && ParameterLengths[0] != -1)
                {
                    vm.PushCallStack(string.Format("{0}\t[{1}]", reps[new List <int>(ParameterLengths).IndexOf(args.Length)], location));
                }
                else if (reps.Count == 0)
                {
                    vm.PushCallStack(string.Format("{0}\t[{1}]", reps[0]));
                }
            }

            if (ParameterLengths[0] != -1)
            {
                foreach (int len in ParameterLengths)
                {
                    if (len == args.Length)
                    {
                        return(Target(vm, Parent, location, args));
                    }
                }
                vm.RaiseException(HassiumArgLengthException.ArgLengthExceptionTypeDef._new(vm, null, location, this, new HassiumInt(ParameterLengths[0]), new HassiumInt(args.Length)));
                return(Null);
            }

            return(Target(vm, Parent, location, args));
        }
示例#2
0
        public override HassiumObject Invoke(VirtualMachine vm, SourceLocation location, params HassiumObject[] args)
        {
            if (SourceRepresentation != string.Empty)
            {
                vm.PushCallStack(string.Format("{0}\t[{1}]", SourceRepresentation, location));
            }
            if (SourceRepresentation != string.Empty || Name == "__init__")
            {
                vm.StackFrame.PushFrame();
            }

            int i = 0;

            foreach (var param in Parameters)
            {
                // If there's more arguments provided than called for
                if (i >= args.Length)
                {
                    vm.RaiseException(HassiumArgLengthException.ArgLengthExceptionTypeDef._new(vm, null, location, this, new HassiumInt(Parameters.Count), new HassiumInt(args.Length)));
                    return(Null);
                }

                var arg = args[i++];
                if (param.Key.FunctionParameterType == FunctionParameterType.Variadic)
                {
                    if (arg is HassiumList || arg is HassiumTuple)
                    {
                        vm.StackFrame.Add(param.Value, arg);
                    }
                    else
                    {
                        HassiumList list = new HassiumList(new HassiumObject[0]);
                        for (--i; i < args.Length; i++)
                        {
                            HassiumList.add(vm, list, location, args[i]);
                        }
                        vm.StackFrame.Add(param.Value, list);
                    }
                    break;
                }
                else if (param.Key.FunctionParameterType == FunctionParameterType.Enforced)
                {
                    var enforcedType = vm.ExecuteMethod(param.Key.EnforcedType);
                    if (enforcedType is HassiumTrait)
                    {
                        if (!(enforcedType as HassiumTrait).Is(vm, location, arg).Bool)
                        {
                            vm.RaiseException(HassiumConversionFailedException.ConversionFailedExceptionTypeDef._new(vm, null, location, arg, enforcedType));
                            return(Null);
                        }
                    }
                    else if (!arg.Types.Contains(enforcedType))
                    {
                        vm.RaiseException(HassiumConversionFailedException.ConversionFailedExceptionTypeDef._new(vm, null, location, arg, enforcedType));
                        return(Null);
                    }
                }
                vm.StackFrame.Add(param.Value, arg);
            }

            // If there's less arguments than called for
            if (i < args.Length)
            {
                vm.RaiseException(HassiumArgLengthException.ArgLengthExceptionTypeDef._new(vm, null, location, this, new HassiumInt(Parameters.Count), new HassiumInt(args.Length)));
                return(Null);
            }

            if (IsConstructor)
            {
                HassiumClass clazz = new HassiumClass((Parent as HassiumClass).Name);
                clazz.BoundAttributes = CloneDictionary(Parent.BoundAttributes);
                var parent = (Parent as HassiumClass);
                clazz.DocStr = parent.DocStr;
                clazz.AddType(parent.TypeDefinition);

                foreach (var inherit in parent.Inherits)
                {
                    foreach (var attrib in CloneDictionary(vm.ExecuteMethod(inherit).GetAttributes()))
                    {
                        if (!clazz.ContainsAttribute(attrib.Key))
                        {
                            attrib.Value.Parent = clazz;
                            clazz.BoundAttributes.Add(attrib.Key, attrib.Value);
                        }
                    }
                }

                foreach (var type in Parent.Types)
                {
                    clazz.AddType(type as HassiumTypeDefinition);
                }
                foreach (var attrib in clazz.BoundAttributes.Values)
                {
                    attrib.Parent = clazz;
                }
                vm.ExecuteMethod(clazz.BoundAttributes["new"] as HassiumMethod);
                vm.PopCallStack();
                vm.StackFrame.PopFrame();
                return(clazz);
            }

            var ret = vm.ExecuteMethod(this);

            if (ReturnType != null)
            {
                var enforcedType = vm.ExecuteMethod(ReturnType);
                enforcedType = enforcedType is HassiumTypeDefinition ? enforcedType : enforcedType.Type();
                if (!ret.Types.Contains(enforcedType))
                {
                    vm.RaiseException(HassiumConversionFailedException.ConversionFailedExceptionTypeDef._new(vm, null, location, ret, enforcedType));
                    return(this);
                }
            }

            if (Name != "__init__" && Name != string.Empty)
            {
                vm.StackFrame.PopFrame();
            }
            if (SourceRepresentation != string.Empty && Name != "__init__")
            {
                vm.PopCallStack();
            }
            return(ret);
        }