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); } }
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); } }
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); }