github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/runtime/builtin_types.go (about)

     1  // Copyright 2016 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package grumpy
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"math"
    21  	"math/big"
    22  	"strings"
    23  	"unicode"
    24  )
    25  
    26  var (
    27  	// Builtins contains all of the Python built-in identifiers.
    28  	Builtins   = NewDict()
    29  	builtinStr = NewStr("__builtin__")
    30  	// ExceptionTypes contains all builtin exception types.
    31  	ExceptionTypes []*Type
    32  	// EllipsisType is the object representing the Python 'ellipsis' type
    33  	EllipsisType = newSimpleType("ellipsis", ObjectType)
    34  	// Ellipsis is the singleton ellipsis object representing the Python
    35  	// 'Ellipsis' object.
    36  	Ellipsis = &Object{typ: EllipsisType}
    37  	// NoneType is the object representing the Python 'NoneType' type.
    38  	NoneType = newSimpleType("NoneType", ObjectType)
    39  	// None is the singleton NoneType object representing the Python 'None'
    40  	// object.
    41  	None = &Object{typ: NoneType}
    42  	// NotImplementedType is the object representing the Python
    43  	// 'NotImplementedType' object.
    44  	NotImplementedType = newSimpleType("NotImplementedType", ObjectType)
    45  	// NotImplemented is the singleton NotImplementedType object
    46  	// representing the Python 'NotImplemented' object.
    47  	NotImplemented   = newObject(NotImplementedType)
    48  	unboundLocalType = newSimpleType("UnboundLocalType", ObjectType)
    49  	// UnboundLocal is a singleton held by local variables in generated
    50  	// code before they are bound.
    51  	UnboundLocal = newObject(unboundLocalType)
    52  )
    53  
    54  func ellipsisRepr(*Frame, *Object) (*Object, *BaseException) {
    55  	return NewStr("Ellipsis").ToObject(), nil
    56  }
    57  
    58  func noneRepr(*Frame, *Object) (*Object, *BaseException) {
    59  	return NewStr("None").ToObject(), nil
    60  }
    61  
    62  func notImplementedRepr(*Frame, *Object) (*Object, *BaseException) {
    63  	return NewStr("NotImplemented").ToObject(), nil
    64  }
    65  
    66  func initEllipsisType(map[string]*Object) {
    67  	EllipsisType.flags &= ^(typeFlagInstantiable | typeFlagBasetype)
    68  	EllipsisType.slots.Repr = &unaryOpSlot{ellipsisRepr}
    69  }
    70  
    71  func initNoneType(map[string]*Object) {
    72  	NoneType.flags &= ^(typeFlagInstantiable | typeFlagBasetype)
    73  	NoneType.slots.Repr = &unaryOpSlot{noneRepr}
    74  }
    75  
    76  func initNotImplementedType(map[string]*Object) {
    77  	NotImplementedType.flags &= ^(typeFlagInstantiable | typeFlagBasetype)
    78  	NotImplementedType.slots.Repr = &unaryOpSlot{notImplementedRepr}
    79  }
    80  
    81  func initUnboundLocalType(map[string]*Object) {
    82  	unboundLocalType.flags &= ^(typeFlagInstantiable | typeFlagBasetype)
    83  }
    84  
    85  type typeState int
    86  
    87  const (
    88  	typeStateNotReady typeState = iota
    89  	typeStateInitializing
    90  	typeStateReady
    91  )
    92  
    93  type builtinTypeInit func(map[string]*Object)
    94  
    95  type builtinTypeInfo struct {
    96  	state  typeState
    97  	init   builtinTypeInit
    98  	global bool
    99  }
   100  
   101  var builtinTypes = map[*Type]*builtinTypeInfo{
   102  	ArithmeticErrorType:           {global: true},
   103  	AssertionErrorType:            {global: true},
   104  	AttributeErrorType:            {global: true},
   105  	BaseExceptionType:             {init: initBaseExceptionType, global: true},
   106  	BaseStringType:                {init: initBaseStringType, global: true},
   107  	BoolType:                      {init: initBoolType, global: true},
   108  	ByteArrayType:                 {init: initByteArrayType, global: true},
   109  	BytesWarningType:              {global: true},
   110  	callableIteratorType:          {init: initCallableIteratorType},
   111  	CodeType:                      {},
   112  	ComplexType:                   {init: initComplexType, global: true},
   113  	ClassMethodType:               {init: initClassMethodType, global: true},
   114  	DeprecationWarningType:        {global: true},
   115  	dictItemIteratorType:          {init: initDictItemIteratorType},
   116  	dictKeyIteratorType:           {init: initDictKeyIteratorType},
   117  	dictValueIteratorType:         {init: initDictValueIteratorType},
   118  	DictType:                      {init: initDictType, global: true},
   119  	EllipsisType:                  {init: initEllipsisType, global: true},
   120  	enumerateType:                 {init: initEnumerateType, global: true},
   121  	EnvironmentErrorType:          {global: true},
   122  	EOFErrorType:                  {global: true},
   123  	ExceptionType:                 {global: true},
   124  	FileType:                      {init: initFileType, global: true},
   125  	FloatType:                     {init: initFloatType, global: true},
   126  	FrameType:                     {init: initFrameType},
   127  	FrozenSetType:                 {init: initFrozenSetType, global: true},
   128  	FunctionType:                  {init: initFunctionType},
   129  	FutureWarningType:             {global: true},
   130  	GeneratorType:                 {init: initGeneratorType},
   131  	ImportErrorType:               {global: true},
   132  	ImportWarningType:             {global: true},
   133  	IndexErrorType:                {global: true},
   134  	IntType:                       {init: initIntType, global: true},
   135  	IOErrorType:                   {global: true},
   136  	KeyboardInterruptType:         {global: true},
   137  	KeyErrorType:                  {global: true},
   138  	listIteratorType:              {init: initListIteratorType},
   139  	ListType:                      {init: initListType, global: true},
   140  	LongType:                      {init: initLongType, global: true},
   141  	LookupErrorType:               {global: true},
   142  	MemoryErrorType:               {global: true},
   143  	MethodType:                    {init: initMethodType},
   144  	ModuleType:                    {init: initModuleType},
   145  	NameErrorType:                 {global: true},
   146  	nativeBoolMetaclassType:       {init: initNativeBoolMetaclassType},
   147  	nativeFuncType:                {init: initNativeFuncType},
   148  	nativeMetaclassType:           {init: initNativeMetaclassType},
   149  	nativeSliceType:               {init: initNativeSliceType},
   150  	nativeType:                    {init: initNativeType},
   151  	NoneType:                      {init: initNoneType, global: true},
   152  	NotImplementedErrorType:       {global: true},
   153  	NotImplementedType:            {init: initNotImplementedType, global: true},
   154  	ObjectType:                    {init: initObjectType, global: true},
   155  	OSErrorType:                   {global: true},
   156  	OverflowErrorType:             {global: true},
   157  	PendingDeprecationWarningType: {global: true},
   158  	PropertyType:                  {init: initPropertyType, global: true},
   159  	rangeIteratorType:             {init: initRangeIteratorType, global: true},
   160  	ReferenceErrorType:            {global: true},
   161  	RuntimeErrorType:              {global: true},
   162  	RuntimeWarningType:            {global: true},
   163  	seqIteratorType:               {init: initSeqIteratorType},
   164  	SetType:                       {init: initSetType, global: true},
   165  	sliceIteratorType:             {init: initSliceIteratorType},
   166  	SliceType:                     {init: initSliceType, global: true},
   167  	StandardErrorType:             {global: true},
   168  	StaticMethodType:              {init: initStaticMethodType, global: true},
   169  	StopIterationType:             {global: true},
   170  	StrType:                       {init: initStrType, global: true},
   171  	superType:                     {init: initSuperType, global: true},
   172  	SyntaxErrorType:               {global: true},
   173  	SyntaxWarningType:             {global: true},
   174  	SystemErrorType:               {global: true},
   175  	SystemExitType:                {global: true, init: initSystemExitType},
   176  	TracebackType:                 {init: initTracebackType},
   177  	TupleType:                     {init: initTupleType, global: true},
   178  	TypeErrorType:                 {global: true},
   179  	TypeType:                      {init: initTypeType, global: true},
   180  	UnboundLocalErrorType:         {global: true},
   181  	unboundLocalType:              {init: initUnboundLocalType},
   182  	UnicodeDecodeErrorType:        {global: true},
   183  	UnicodeEncodeErrorType:        {global: true},
   184  	UnicodeErrorType:              {global: true},
   185  	UnicodeType:                   {init: initUnicodeType, global: true},
   186  	UnicodeWarningType:            {global: true},
   187  	UserWarningType:               {global: true},
   188  	ValueErrorType:                {global: true},
   189  	WarningType:                   {global: true},
   190  	WeakRefType:                   {init: initWeakRefType},
   191  	xrangeType:                    {init: initXRangeType, global: true},
   192  	ZeroDivisionErrorType:         {global: true},
   193  }
   194  
   195  func initBuiltinType(typ *Type, info *builtinTypeInfo) {
   196  	if info.state == typeStateReady {
   197  		return
   198  	}
   199  	if info.state == typeStateInitializing {
   200  		logFatal(fmt.Sprintf("cycle in type initialization for: %s", typ.name))
   201  	}
   202  	info.state = typeStateInitializing
   203  	for _, base := range typ.bases {
   204  		baseInfo, ok := builtinTypes[base]
   205  		if !ok {
   206  			logFatal(fmt.Sprintf("base type not registered for: %s", typ.name))
   207  		}
   208  		initBuiltinType(base, baseInfo)
   209  	}
   210  	prepareBuiltinType(typ, info.init)
   211  	info.state = typeStateReady
   212  	if typ.isSubclass(BaseExceptionType) {
   213  		ExceptionTypes = append(ExceptionTypes, typ)
   214  	}
   215  }
   216  
   217  func builtinAbs(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   218  	if raised := checkFunctionArgs(f, "abs", args, ObjectType); raised != nil {
   219  		return nil, raised
   220  	}
   221  	return Abs(f, args[0])
   222  }
   223  
   224  func builtinMapFn(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   225  	argc := len(args)
   226  	if argc < 2 {
   227  		return nil, f.RaiseType(TypeErrorType, "map() requires at least two args")
   228  	}
   229  	result := make([]*Object, 0, 2)
   230  	z, raised := zipLongest(f, args[1:])
   231  	if raised != nil {
   232  		return nil, raised
   233  	}
   234  	for _, tuple := range z {
   235  		if args[0] == None {
   236  			if argc == 2 {
   237  				result = append(result, tuple[0])
   238  			} else {
   239  				result = append(result, NewTuple(tuple...).ToObject())
   240  			}
   241  		} else {
   242  			ret, raised := args[0].Call(f, tuple, nil)
   243  			if raised != nil {
   244  				return nil, raised
   245  			}
   246  			result = append(result, ret)
   247  		}
   248  	}
   249  
   250  	return NewList(result...).ToObject(), nil
   251  }
   252  
   253  func builtinFilter(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   254  	if raised := checkMethodArgs(f, "filter", args, ObjectType, ObjectType); raised != nil {
   255  		return nil, raised
   256  	}
   257  	fn := args[0]
   258  	l := args[1]
   259  	filterFunc := IsTrue
   260  	if fn != None {
   261  		filterFunc = func(f *Frame, o *Object) (bool, *BaseException) {
   262  			result, raised := fn.Call(f, Args{o}, nil)
   263  			if raised != nil {
   264  				return false, raised
   265  			}
   266  			return IsTrue(f, result)
   267  		}
   268  	}
   269  	switch {
   270  	// CPython will return the same type if the second type is tuple or string, else return a list.
   271  	case l.isInstance(TupleType):
   272  		result := make([]*Object, 0)
   273  		for _, item := range toTupleUnsafe(l).elems {
   274  			ret, raised := filterFunc(f, item)
   275  			if raised != nil {
   276  				return nil, raised
   277  			}
   278  			if ret {
   279  				result = append(result, item)
   280  			}
   281  		}
   282  		return NewTuple(result...).ToObject(), nil
   283  	case l.isInstance(StrType):
   284  		if fn == None {
   285  			return l, nil
   286  		}
   287  		var result bytes.Buffer
   288  		for _, item := range []byte(toStrUnsafe(l).Value()) {
   289  			ret, raised := filterFunc(f, NewStr(string(item)).ToObject())
   290  			if raised != nil {
   291  				return nil, raised
   292  			}
   293  			if ret {
   294  				result.WriteByte(item)
   295  			}
   296  		}
   297  		return NewStr(result.String()).ToObject(), nil
   298  	case l.isInstance(UnicodeType):
   299  		if fn == None {
   300  			return l, nil
   301  		}
   302  		var result []rune
   303  		for _, item := range toUnicodeUnsafe(l).Value() {
   304  			ret, raised := filterFunc(f, NewUnicodeFromRunes([]rune{item}).ToObject())
   305  			if raised != nil {
   306  				return nil, raised
   307  			}
   308  			if ret {
   309  				result = append(result, item)
   310  			}
   311  		}
   312  		return NewUnicodeFromRunes(result).ToObject(), nil
   313  	default:
   314  		result := make([]*Object, 0)
   315  		raised := seqForEach(f, l, func(item *Object) (raised *BaseException) {
   316  			ret, raised := filterFunc(f, item)
   317  			if raised != nil {
   318  				return raised
   319  			}
   320  			if ret {
   321  				result = append(result, item)
   322  			}
   323  			return nil
   324  		})
   325  		if raised != nil {
   326  			return nil, raised
   327  		}
   328  		return NewList(result...).ToObject(), nil
   329  	}
   330  }
   331  
   332  func builtinAll(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   333  	if raised := checkFunctionArgs(f, "all", args, ObjectType); raised != nil {
   334  		return nil, raised
   335  	}
   336  	pred := func(o *Object) (bool, *BaseException) {
   337  		ret, raised := IsTrue(f, o)
   338  		if raised != nil {
   339  			return false, raised
   340  		}
   341  		return !ret, nil
   342  	}
   343  	foundFalseItem, raised := seqFindFirst(f, args[0], pred)
   344  	if raised != nil {
   345  		return nil, raised
   346  	}
   347  	return GetBool(!foundFalseItem).ToObject(), raised
   348  }
   349  
   350  func builtinAny(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   351  	if raised := checkFunctionArgs(f, "any", args, ObjectType); raised != nil {
   352  		return nil, raised
   353  	}
   354  	pred := func(o *Object) (bool, *BaseException) {
   355  		ret, raised := IsTrue(f, o)
   356  		if raised != nil {
   357  			return false, raised
   358  		}
   359  		return ret, nil
   360  	}
   361  	foundTrueItem, raised := seqFindFirst(f, args[0], pred)
   362  	if raised != nil {
   363  		return nil, raised
   364  	}
   365  	return GetBool(foundTrueItem).ToObject(), raised
   366  }
   367  
   368  func builtinBin(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   369  	if raised := checkFunctionArgs(f, "bin", args, ObjectType); raised != nil {
   370  		return nil, raised
   371  	}
   372  	index, raised := Index(f, args[0])
   373  	if raised != nil {
   374  		return nil, raised
   375  	}
   376  	if index == nil {
   377  		format := "%s object cannot be interpreted as an index"
   378  		return nil, f.RaiseType(TypeErrorType, fmt.Sprintf(format, args[0].typ.Name()))
   379  	}
   380  	return NewStr(numberToBase("0b", 2, index)).ToObject(), nil
   381  }
   382  
   383  func builtinCallable(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   384  	if raised := checkFunctionArgs(f, "callable", args, ObjectType); raised != nil {
   385  		return nil, raised
   386  	}
   387  	o := args[0]
   388  	if call := o.Type().slots.Call; call == nil {
   389  		return False.ToObject(), nil
   390  	}
   391  	return True.ToObject(), nil
   392  }
   393  
   394  func builtinChr(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   395  	if raised := checkFunctionArgs(f, "chr", args, IntType); raised != nil {
   396  		return nil, raised
   397  	}
   398  	i := toIntUnsafe(args[0]).Value()
   399  	if i < 0 || i > 255 {
   400  		return nil, f.RaiseType(ValueErrorType, "chr() arg not in range(256)")
   401  	}
   402  	return NewStr(string([]byte{byte(i)})).ToObject(), nil
   403  }
   404  
   405  func builtinCmp(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   406  	if raised := checkFunctionArgs(f, "cmp", args, ObjectType, ObjectType); raised != nil {
   407  		return nil, raised
   408  	}
   409  	return Compare(f, args[0], args[1])
   410  }
   411  
   412  func builtinDelAttr(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   413  	if raised := checkFunctionArgs(f, "delattr", args, ObjectType, StrType); raised != nil {
   414  		return nil, raised
   415  	}
   416  	return None, DelAttr(f, args[0], toStrUnsafe(args[1]))
   417  }
   418  
   419  func builtinDir(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   420  	// TODO: Support __dir__.
   421  	if raised := checkFunctionArgs(f, "dir", args, ObjectType); raised != nil {
   422  		return nil, raised
   423  	}
   424  	d := NewDict()
   425  	o := args[0]
   426  	switch {
   427  	case o.isInstance(TypeType):
   428  		for _, t := range toTypeUnsafe(o).mro {
   429  			if raised := d.Update(f, t.Dict().ToObject()); raised != nil {
   430  				return nil, raised
   431  			}
   432  		}
   433  	case o.isInstance(ModuleType):
   434  		d.Update(f, o.Dict().ToObject())
   435  	default:
   436  		d = NewDict()
   437  		if dict := o.Dict(); dict != nil {
   438  			if raised := d.Update(f, dict.ToObject()); raised != nil {
   439  				return nil, raised
   440  			}
   441  		}
   442  		for _, t := range o.typ.mro {
   443  			if raised := d.Update(f, t.Dict().ToObject()); raised != nil {
   444  				return nil, raised
   445  			}
   446  		}
   447  	}
   448  	l := d.Keys(f)
   449  	if raised := l.Sort(f); raised != nil {
   450  		return nil, raised
   451  	}
   452  	return l.ToObject(), nil
   453  }
   454  
   455  func builtinDivMod(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   456  	if raised := checkFunctionArgs(f, "divmod", args, ObjectType, ObjectType); raised != nil {
   457  		return nil, raised
   458  	}
   459  	return DivMod(f, args[0], args[1])
   460  }
   461  
   462  func builtinFrame(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   463  	if raised := checkFunctionArgs(f, "__frame__", args); raised != nil {
   464  		return nil, raised
   465  	}
   466  	f.taken = true
   467  	return f.ToObject(), nil
   468  }
   469  
   470  func builtinGetAttr(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   471  	expectedTypes := []*Type{ObjectType, StrType, ObjectType}
   472  	argc := len(args)
   473  	if argc == 2 {
   474  		expectedTypes = expectedTypes[:2]
   475  	}
   476  	if raised := checkFunctionArgs(f, "getattr", args, expectedTypes...); raised != nil {
   477  		return nil, raised
   478  	}
   479  	var def *Object
   480  	if argc == 3 {
   481  		def = args[2]
   482  	}
   483  	return GetAttr(f, args[0], toStrUnsafe(args[1]), def)
   484  }
   485  
   486  func builtinGlobals(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   487  	if raised := checkFunctionArgs(f, "globals", args); raised != nil {
   488  		return nil, raised
   489  	}
   490  	return f.globals.ToObject(), nil
   491  }
   492  
   493  func builtinHasAttr(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   494  	if raised := checkFunctionArgs(f, "hasattr", args, ObjectType, StrType); raised != nil {
   495  		return nil, raised
   496  	}
   497  	if _, raised := GetAttr(f, args[0], toStrUnsafe(args[1]), nil); raised != nil {
   498  		if raised.isInstance(AttributeErrorType) {
   499  			f.RestoreExc(nil, nil)
   500  			return False.ToObject(), nil
   501  		}
   502  		return nil, raised
   503  	}
   504  	return True.ToObject(), nil
   505  }
   506  
   507  func builtinHash(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   508  	if raised := checkFunctionArgs(f, "hash", args, ObjectType); raised != nil {
   509  		return nil, raised
   510  	}
   511  	h, raised := Hash(f, args[0])
   512  	if raised != nil {
   513  		return nil, raised
   514  	}
   515  	return h.ToObject(), nil
   516  }
   517  
   518  func builtinHex(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   519  	// In Python3 we would call __index__ similarly to builtinBin().
   520  	if raised := checkFunctionArgs(f, "hex", args, ObjectType); raised != nil {
   521  		return nil, raised
   522  	}
   523  	return Hex(f, args[0])
   524  }
   525  
   526  func builtinID(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   527  	if raised := checkFunctionArgs(f, "id", args, ObjectType); raised != nil {
   528  		return nil, raised
   529  	}
   530  	return NewInt(int(uintptr(args[0].toPointer()))).ToObject(), nil
   531  }
   532  
   533  func builtinIsInstance(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   534  	if raised := checkFunctionArgs(f, "isinstance", args, ObjectType, ObjectType); raised != nil {
   535  		return nil, raised
   536  	}
   537  	ret, raised := IsInstance(f, args[0], args[1])
   538  	if raised != nil {
   539  		return nil, raised
   540  	}
   541  	return GetBool(ret).ToObject(), nil
   542  }
   543  
   544  func builtinIsSubclass(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   545  	if raised := checkFunctionArgs(f, "issubclass", args, ObjectType, ObjectType); raised != nil {
   546  		return nil, raised
   547  	}
   548  	ret, raised := IsSubclass(f, args[0], args[1])
   549  	if raised != nil {
   550  		return nil, raised
   551  	}
   552  	return GetBool(ret).ToObject(), nil
   553  }
   554  
   555  func builtinIter(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   556  	argc := len(args)
   557  	expectedTypes := []*Type{ObjectType, ObjectType}
   558  	if argc == 1 {
   559  		expectedTypes = expectedTypes[:1]
   560  	}
   561  	if raised := checkFunctionArgs(f, "iter", args, expectedTypes...); raised != nil {
   562  		return nil, raised
   563  	}
   564  	if argc == 1 {
   565  		return Iter(f, args[0])
   566  	}
   567  	return IterCallable(f, args[0], args[1])
   568  }
   569  
   570  func builtinLen(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   571  	if raised := checkFunctionArgs(f, "len", args, ObjectType); raised != nil {
   572  		return nil, raised
   573  	}
   574  	ret, raised := Len(f, args[0])
   575  	if raised != nil {
   576  		return nil, raised
   577  	}
   578  	return ret.ToObject(), nil
   579  }
   580  
   581  func builtinMax(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   582  	return builtinMinMax(f, true, args, kwargs)
   583  }
   584  
   585  func builtinMin(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   586  	return builtinMinMax(f, false, args, kwargs)
   587  }
   588  
   589  func builtinNext(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   590  	if raised := checkFunctionArgs(f, "next", args, ObjectType); raised != nil {
   591  		return nil, raised
   592  	}
   593  	ret, raised := Next(f, args[0])
   594  	if raised != nil {
   595  		return nil, raised
   596  	}
   597  	if ret != nil {
   598  		return ret, nil
   599  	}
   600  	return nil, f.Raise(StopIterationType.ToObject(), nil, nil)
   601  }
   602  
   603  func builtinOct(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   604  	// In Python3 we would call __index__ similarly to builtinBin().
   605  	if raised := checkFunctionArgs(f, "oct", args, ObjectType); raised != nil {
   606  		return nil, raised
   607  	}
   608  	return Oct(f, args[0])
   609  }
   610  
   611  func builtinOpen(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   612  	return FileType.Call(f, args, kwargs)
   613  }
   614  
   615  func builtinOrd(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   616  	const lenMsg = "ord() expected a character, but string of length %d found"
   617  	if raised := checkFunctionArgs(f, "ord", args, BaseStringType); raised != nil {
   618  		return nil, raised
   619  	}
   620  	o := args[0]
   621  	var result int
   622  	if o.isInstance(StrType) {
   623  		s := toStrUnsafe(o).Value()
   624  		if numChars := len(s); numChars != 1 {
   625  			return nil, f.RaiseType(ValueErrorType, fmt.Sprintf(lenMsg, numChars))
   626  		}
   627  		result = int(([]byte(s))[0])
   628  	} else {
   629  		s := toUnicodeUnsafe(o).Value()
   630  		if numChars := len(s); numChars != 1 {
   631  			return nil, f.RaiseType(ValueErrorType, fmt.Sprintf(lenMsg, numChars))
   632  		}
   633  		result = int(s[0])
   634  	}
   635  	return NewInt(result).ToObject(), nil
   636  }
   637  
   638  func builtinPower(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   639  	expectedTypes := []*Type{ObjectType, ObjectType}
   640  	if len(args) == 3 {
   641  		return nil, f.RaiseType(NotImplementedErrorType, "third parameter is not supported now")
   642  	}
   643  	if raised := checkFunctionArgs(f, "pow", args, expectedTypes...); raised != nil {
   644  		return nil, raised
   645  	}
   646  	return Pow(f, args[0], args[1])
   647  }
   648  
   649  func builtinPrint(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   650  	sep := " "
   651  	end := "\n"
   652  	file := Stdout
   653  	for _, kwarg := range kwargs {
   654  		switch kwarg.Name {
   655  		case "sep":
   656  			kwsep, raised := ToStr(f, kwarg.Value)
   657  			if raised != nil {
   658  				return nil, raised
   659  			}
   660  			sep = kwsep.Value()
   661  		case "end":
   662  			kwend, raised := ToStr(f, kwarg.Value)
   663  			if raised != nil {
   664  				return nil, raised
   665  			}
   666  			end = kwend.Value()
   667  		case "file":
   668  			// TODO: need to map Python sys.stdout, sys.stderr etc. to os.Stdout,
   669  			// os.Stderr, but for other file-like objects would need to recover
   670  			// to the file descriptor probably
   671  		}
   672  	}
   673  	return nil, pyPrint(f, args, sep, end, file)
   674  }
   675  
   676  func builtinRange(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   677  	r, raised := xrangeType.Call(f, args, nil)
   678  	if raised != nil {
   679  		return nil, raised
   680  	}
   681  	return ListType.Call(f, []*Object{r}, nil)
   682  }
   683  
   684  func builtinRawInput(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   685  	if len(args) > 1 {
   686  		msg := fmt.Sprintf("[raw_]input expcted at most 1 arguments, got %d", len(args))
   687  		return nil, f.RaiseType(TypeErrorType, msg)
   688  	}
   689  
   690  	if Stdin == nil {
   691  		msg := fmt.Sprintf("[raw_]input: lost sys.stdin")
   692  		return nil, f.RaiseType(RuntimeErrorType, msg)
   693  	}
   694  
   695  	if Stdout == nil {
   696  		msg := fmt.Sprintf("[raw_]input: lost sys.stdout")
   697  		return nil, f.RaiseType(RuntimeErrorType, msg)
   698  	}
   699  
   700  	if len(args) == 1 {
   701  		err := pyPrint(f, args, "", "", Stdout)
   702  		if err != nil {
   703  			return nil, err
   704  		}
   705  	}
   706  
   707  	line, err := Stdin.reader.ReadString('\n')
   708  	if err != nil {
   709  		return nil, f.RaiseType(EOFErrorType, "EOF when reading a line")
   710  	}
   711  	line = strings.TrimRight(line, "\n")
   712  	return NewStr(line).ToObject(), nil
   713  }
   714  
   715  func builtinRepr(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   716  	if raised := checkFunctionArgs(f, "repr", args, ObjectType); raised != nil {
   717  		return nil, raised
   718  	}
   719  	s, raised := Repr(f, args[0])
   720  	if raised != nil {
   721  		return nil, raised
   722  	}
   723  	return s.ToObject(), nil
   724  }
   725  
   726  func builtinRound(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   727  	argc := len(args)
   728  	expectedTypes := []*Type{ObjectType, ObjectType}
   729  	if argc == 1 {
   730  		expectedTypes = expectedTypes[:1]
   731  	}
   732  	if raised := checkFunctionArgs(f, "round", args, expectedTypes...); raised != nil {
   733  		return nil, raised
   734  	}
   735  	ndigits := 0
   736  	if argc > 1 {
   737  		var raised *BaseException
   738  		if ndigits, raised = IndexInt(f, args[1]); raised != nil {
   739  			return nil, raised
   740  		}
   741  	}
   742  	number, isFloat := floatCoerce(args[0])
   743  
   744  	if !isFloat {
   745  		return nil, f.RaiseType(TypeErrorType, "a float is required")
   746  	}
   747  
   748  	if math.IsNaN(number) || math.IsInf(number, 0) || number == 0.0 {
   749  		return NewFloat(number).ToObject(), nil
   750  	}
   751  
   752  	neg := false
   753  	if number < 0 {
   754  		neg = true
   755  		number = -number
   756  	}
   757  	pow := math.Pow(10.0, float64(ndigits))
   758  	result := math.Floor(number*pow+0.5) / pow
   759  	if neg {
   760  		result = -result
   761  	}
   762  	return NewFloat(result).ToObject(), nil
   763  }
   764  
   765  func builtinSetAttr(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   766  	if raised := checkFunctionArgs(f, "setattr", args, ObjectType, StrType, ObjectType); raised != nil {
   767  		return nil, raised
   768  	}
   769  	return None, SetAttr(f, args[0], toStrUnsafe(args[1]), args[2])
   770  }
   771  
   772  func builtinSorted(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   773  	// TODO: Support (cmp=None, key=None, reverse=False)
   774  	if raised := checkFunctionArgs(f, "sorted", args, ObjectType); raised != nil {
   775  		return nil, raised
   776  	}
   777  	result, raised := ListType.Call(f, Args{args[0]}, nil)
   778  	if raised != nil {
   779  		return nil, raised
   780  	}
   781  	toListUnsafe(result).Sort(f)
   782  	// Implement reverse.
   783  	reverse, raised := IsTrue(f, kwargs.get("reverse", None))
   784  	if raised != nil {
   785  		return nil, raised
   786  	}
   787  	if reverse {
   788  		toListUnsafe(result).Reverse()
   789  	}
   790  	return result, nil
   791  }
   792  
   793  func builtinSum(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   794  	argc := len(args)
   795  	expectedTypes := []*Type{ObjectType, ObjectType}
   796  	if argc == 1 {
   797  		expectedTypes = expectedTypes[:1]
   798  	}
   799  	if raised := checkFunctionArgs(f, "sum", args, expectedTypes...); raised != nil {
   800  		return nil, raised
   801  	}
   802  	var result *Object
   803  	if argc > 1 {
   804  		if args[1].typ == StrType {
   805  			return nil, f.RaiseType(TypeErrorType, "sum() can't sum strings [use ''.join(seq) instead]")
   806  		}
   807  		result = args[1]
   808  	} else {
   809  		result = NewInt(0).ToObject()
   810  	}
   811  	raised := seqForEach(f, args[0], func(o *Object) (raised *BaseException) {
   812  		result, raised = Add(f, result, o)
   813  		return raised
   814  	})
   815  
   816  	if raised != nil {
   817  		return nil, raised
   818  	}
   819  	return result, nil
   820  }
   821  
   822  func builtinUniChr(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   823  	if raised := checkFunctionArgs(f, "unichr", args, IntType); raised != nil {
   824  		return nil, raised
   825  	}
   826  	i := toIntUnsafe(args[0]).Value()
   827  	if i < 0 || i > unicode.MaxRune {
   828  		return nil, f.RaiseType(ValueErrorType, fmt.Sprintf("unichr() arg not in range(0x%x)", unicode.MaxRune))
   829  	}
   830  	return NewUnicodeFromRunes([]rune{rune(i)}).ToObject(), nil
   831  }
   832  
   833  func builtinZip(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   834  	argc := len(args)
   835  	if argc == 0 {
   836  		return NewList().ToObject(), nil
   837  	}
   838  	result := make([]*Object, 0, 2)
   839  	iters, raised := initIters(f, args)
   840  	if raised != nil {
   841  		return nil, raised
   842  	}
   843  
   844  Outer:
   845  	for {
   846  		elems := make([]*Object, argc)
   847  		for i, iter := range iters {
   848  			elem, raised := Next(f, iter)
   849  			if raised != nil {
   850  				if raised.isInstance(StopIterationType) {
   851  					f.RestoreExc(nil, nil)
   852  					break Outer
   853  				}
   854  				return nil, raised
   855  			}
   856  			elems[i] = elem
   857  		}
   858  		result = append(result, NewTuple(elems...).ToObject())
   859  	}
   860  	return NewList(result...).ToObject(), nil
   861  }
   862  
   863  func init() {
   864  	builtinMap := map[string]*Object{
   865  		"__debug__":      False.ToObject(),
   866  		"__frame__":      newBuiltinFunction("__frame__", builtinFrame).ToObject(),
   867  		"abs":            newBuiltinFunction("abs", builtinAbs).ToObject(),
   868  		"all":            newBuiltinFunction("all", builtinAll).ToObject(),
   869  		"any":            newBuiltinFunction("any", builtinAny).ToObject(),
   870  		"bin":            newBuiltinFunction("bin", builtinBin).ToObject(),
   871  		"callable":       newBuiltinFunction("callable", builtinCallable).ToObject(),
   872  		"chr":            newBuiltinFunction("chr", builtinChr).ToObject(),
   873  		"cmp":            newBuiltinFunction("cmp", builtinCmp).ToObject(),
   874  		"delattr":        newBuiltinFunction("delattr", builtinDelAttr).ToObject(),
   875  		"dir":            newBuiltinFunction("dir", builtinDir).ToObject(),
   876  		"divmod":         newBuiltinFunction("divmod", builtinDivMod).ToObject(),
   877  		"Ellipsis":       Ellipsis,
   878  		"False":          False.ToObject(),
   879  		"filter":         newBuiltinFunction("filter", builtinFilter).ToObject(),
   880  		"getattr":        newBuiltinFunction("getattr", builtinGetAttr).ToObject(),
   881  		"globals":        newBuiltinFunction("globals", builtinGlobals).ToObject(),
   882  		"hasattr":        newBuiltinFunction("hasattr", builtinHasAttr).ToObject(),
   883  		"hash":           newBuiltinFunction("hash", builtinHash).ToObject(),
   884  		"hex":            newBuiltinFunction("hex", builtinHex).ToObject(),
   885  		"id":             newBuiltinFunction("id", builtinID).ToObject(),
   886  		"isinstance":     newBuiltinFunction("isinstance", builtinIsInstance).ToObject(),
   887  		"issubclass":     newBuiltinFunction("issubclass", builtinIsSubclass).ToObject(),
   888  		"iter":           newBuiltinFunction("iter", builtinIter).ToObject(),
   889  		"len":            newBuiltinFunction("len", builtinLen).ToObject(),
   890  		"map":            newBuiltinFunction("map", builtinMapFn).ToObject(),
   891  		"max":            newBuiltinFunction("max", builtinMax).ToObject(),
   892  		"min":            newBuiltinFunction("min", builtinMin).ToObject(),
   893  		"next":           newBuiltinFunction("next", builtinNext).ToObject(),
   894  		"None":           None,
   895  		"NotImplemented": NotImplemented,
   896  		"oct":            newBuiltinFunction("oct", builtinOct).ToObject(),
   897  		"open":           newBuiltinFunction("open", builtinOpen).ToObject(),
   898  		"ord":            newBuiltinFunction("ord", builtinOrd).ToObject(),
   899  		"pow":            newBuiltinFunction("pow", builtinPower).ToObject(),
   900  		"print":          newBuiltinFunction("print", builtinPrint).ToObject(),
   901  		"range":          newBuiltinFunction("range", builtinRange).ToObject(),
   902  		"raw_input":      newBuiltinFunction("raw_input", builtinRawInput).ToObject(),
   903  		"repr":           newBuiltinFunction("repr", builtinRepr).ToObject(),
   904  		"round":          newBuiltinFunction("round", builtinRound).ToObject(),
   905  		"setattr":        newBuiltinFunction("setattr", builtinSetAttr).ToObject(),
   906  		"sorted":         newBuiltinFunction("sorted", builtinSorted).ToObject(),
   907  		"sum":            newBuiltinFunction("sum", builtinSum).ToObject(),
   908  		"True":           True.ToObject(),
   909  		"unichr":         newBuiltinFunction("unichr", builtinUniChr).ToObject(),
   910  		"zip":            newBuiltinFunction("zip", builtinZip).ToObject(),
   911  	}
   912  	// Do type initialization in two phases so that we don't have to think
   913  	// about hard-to-understand cycles.
   914  	for typ, info := range builtinTypes {
   915  		initBuiltinType(typ, info)
   916  		if info.global {
   917  			builtinMap[typ.name] = typ.ToObject()
   918  		}
   919  	}
   920  	for name := range builtinMap {
   921  		InternStr(name)
   922  	}
   923  	Builtins = newStringDict(builtinMap)
   924  }
   925  
   926  // builtinMinMax implements the builtin min/max() functions. When doMax is
   927  // true, the max is found, otherwise the min is found. There are two forms of
   928  // the builtins. The first takes a single iterable argument and the result is
   929  // the min/max of the elements of that sequence. The second form takes two or
   930  // more args and returns the min/max of those. For more details see:
   931  // https://docs.python.org/2/library/functions.html#min
   932  func builtinMinMax(f *Frame, doMax bool, args Args, kwargs KWArgs) (*Object, *BaseException) {
   933  	name := "min"
   934  	if doMax {
   935  		name = "max"
   936  	}
   937  	if raised := checkFunctionVarArgs(f, name, args, ObjectType); raised != nil {
   938  		return nil, raised
   939  	}
   940  	keyFunc := kwargs.get("key", nil)
   941  	// selected is the min/max element found so far.
   942  	var selected, selectedKey *Object
   943  	partialFunc := func(o *Object) (raised *BaseException) {
   944  		oKey := o
   945  		if keyFunc != nil {
   946  			oKey, raised = keyFunc.Call(f, Args{o}, nil)
   947  			if raised != nil {
   948  				return raised
   949  			}
   950  		}
   951  		// sel dictates whether o is the new min/max. It defaults to
   952  		// true when selected == nil (we don't yet have a selection).
   953  		sel := true
   954  		if selected != nil {
   955  			result, raised := LT(f, selectedKey, oKey)
   956  			if raised != nil {
   957  				return raised
   958  			}
   959  			lt, raised := IsTrue(f, result)
   960  			if raised != nil {
   961  				return raised
   962  			}
   963  			// Select o when looking for max and selection < o, or
   964  			// when looking for min and o < selection.
   965  			sel = doMax && lt || !doMax && !lt
   966  		}
   967  		if sel {
   968  			selected = o
   969  			selectedKey = oKey
   970  		}
   971  		return nil
   972  	}
   973  	if len(args) == 1 {
   974  		// Take min/max of the single iterable arg passed.
   975  		if raised := seqForEach(f, args[0], partialFunc); raised != nil {
   976  			return nil, raised
   977  		}
   978  		if selected == nil {
   979  			return nil, f.RaiseType(ValueErrorType, fmt.Sprintf("%s() arg is an empty sequence", name))
   980  		}
   981  	} else {
   982  		// Take min/max of the passed args.
   983  		for _, arg := range args {
   984  			if raised := partialFunc(arg); raised != nil {
   985  				return nil, raised
   986  			}
   987  		}
   988  	}
   989  	return selected, nil
   990  }
   991  
   992  // numberToBase implements the builtins "bin", "hex", and "oct".
   993  // base must be between 2 and 36, and o must be an instance of
   994  // IntType or LongType.
   995  func numberToBase(prefix string, base int, o *Object) string {
   996  	z := big.Int{}
   997  	switch {
   998  	case o.isInstance(LongType):
   999  		z = toLongUnsafe(o).value
  1000  	case o.isInstance(IntType):
  1001  		z.SetInt64(int64(toIntUnsafe(o).Value()))
  1002  	default:
  1003  		panic("numberToBase requires an Int or Long argument")
  1004  	}
  1005  	s := z.Text(base)
  1006  	if s[0] == '-' {
  1007  		// Move the negative sign before the prefix.
  1008  		return "-" + prefix + s[1:]
  1009  	}
  1010  	return prefix + s
  1011  }
  1012  
  1013  // initIters return list of initiated Iter instances from the list of
  1014  // iterables.
  1015  func initIters(f *Frame, items []*Object) ([]*Object, *BaseException) {
  1016  	l := len(items)
  1017  	iters := make([]*Object, l)
  1018  	for i, arg := range items {
  1019  		iter, raised := Iter(f, arg)
  1020  		if raised != nil {
  1021  			return nil, raised
  1022  		}
  1023  		iters[i] = iter
  1024  	}
  1025  	return iters, nil
  1026  }
  1027  
  1028  // zipLongest return the list of aggregates elements from each of the
  1029  // iterables. If the iterables are of uneven length, missing values are
  1030  // filled-in with None.
  1031  func zipLongest(f *Frame, args Args) ([][]*Object, *BaseException) {
  1032  	argc := len(args)
  1033  	result := make([][]*Object, 0, 2)
  1034  	iters, raised := initIters(f, args)
  1035  	if raised != nil {
  1036  		return nil, raised
  1037  	}
  1038  
  1039  	for {
  1040  		noItems := true
  1041  		elems := make([]*Object, argc)
  1042  		for i, iter := range iters {
  1043  			if iter == nil {
  1044  				continue
  1045  			}
  1046  			elem, raised := Next(f, iter)
  1047  			if raised != nil {
  1048  				if raised.isInstance(StopIterationType) {
  1049  					iters[i] = nil
  1050  					elems[i] = None
  1051  					f.RestoreExc(nil, nil)
  1052  					continue
  1053  				}
  1054  				return nil, raised
  1055  			}
  1056  			noItems = false
  1057  			elems[i] = elem
  1058  		}
  1059  		if noItems {
  1060  			break
  1061  		}
  1062  		result = append(result, elems)
  1063  	}
  1064  	return result, nil
  1065  }