예제 #1
0
 public override HassiumObject Invoke(VirtualMachine vm, SourceLocation location, params HassiumObject[] args)
 {
     if (BoundAttributes.ContainsKey("new"))
     {
         return(BoundAttributes["new"].Invoke(vm, location, args).AddType(TypeDefinition));
     }
     else if (BoundAttributes.ContainsKey(INVOKE))
     {
         return(BoundAttributes[INVOKE].Invoke(vm, location, args).AddType(TypeDefinition));
     }
     else
     {
         foreach (var inherit in Inherits)
         {
             var inheritClazz = vm.ExecuteMethod(inherit);
             if (inheritClazz is HassiumTypeDefinition)
             {
                 foreach (var attrib in inheritClazz.BoundAttributes)
                 {
                     BoundAttributes.Add(attrib.Key, (attrib.Value.Clone() as HassiumObject).SetSelfReference(this));
                 }
             }
             else
             {
                 foreach (var attrib in HassiumMethod.CloneDictionary(vm.ExecuteMethod(inherit).GetAttributes()))
                 {
                     if (!BoundAttributes.ContainsKey(attrib.Key))
                     {
                         attrib.Value.Parent = this;
                         BoundAttributes.Add(attrib.Key, attrib.Value);
                     }
                 }
             }
         }
         if (BoundAttributes.ContainsKey("new"))
         {
             return(Invoke(vm, location, args).AddType(TypeDefinition));
         }
         vm.RaiseException(HassiumAttribNotFoundException.AttribNotFoundExceptionTypeDef._new(vm, null, location, this, new HassiumString(INVOKE)));
         return(Null);
     }
 }
예제 #2
0
        public override HassiumObject Invoke(VirtualMachine vm, SourceLocation location, params HassiumObject[] args)
        {
            List <HassiumMethod> lengthMatchingMethods = new List <HassiumMethod>();

            foreach (var method in Methods)
            {
                if (method.Parameters.Count == args.Length)
                {
                    lengthMatchingMethods.Add(method);
                }
            }

            if (lengthMatchingMethods.Count == 0)
            {
                vm.RaiseException(HassiumArgLengthException.ArgLengthExceptionTypeDef._new(vm, null, location, this, new HassiumInt(Methods[0].Parameters.Count), new HassiumInt(args.Length)));
                return(Null);
            }
            else if (lengthMatchingMethods.Count == 1)
            {
                return(lengthMatchingMethods[0].Invoke(vm, location, args));
            }
            else
            {
                foreach (var method in lengthMatchingMethods)
                {
                    bool foundMatch = true;
                    int  i          = 0;
                    foreach (var param in method.Parameters)
                    {
                        var arg = args[i++];
                        if (param.Key.FunctionParameterType == Compiler.Parser.FunctionParameterType.Enforced)
                        {
                            if (!vm.Is(arg, vm.ExecuteMethod(param.Key.EnforcedType)).Bool)
                            {
                                foundMatch = false;
                                break;
                            }
                        }
                    }
                    if (foundMatch)
                    {
                        return(method.Invoke(vm, location, args));
                    }
                }
                vm.RaiseException(HassiumArgLengthException.ArgLengthExceptionTypeDef._new(vm, null, location, this, new HassiumInt(Methods[0].Parameters.Count), new HassiumInt(args.Length)));
                return(Null);
            }
        }
예제 #3
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);
        }