Skip to content

Commit be4d292

Browse files
committed
Implement + and * for string, list and tuple
1 parent 21d01bf commit be4d292

File tree

5 files changed

+140
-2
lines changed

5 files changed

+140
-2
lines changed

py/internal.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ func IndexIntCheck(a Object, max int) int {
7070
i += max
7171
}
7272
if i < 0 || i >= max {
73-
// FIXME IndexError
74-
panic("IndexError: list index out of range")
73+
panic(ExceptionNewf(IndexError, "list index out of range"))
7574
}
7675
return i
7776
}

py/list.go

+48
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,55 @@ func (l *List) M__setitem__(key, value Object) Object {
9494
return None
9595
}
9696

97+
func (a *List) M__add__(other Object) Object {
98+
if b, ok := other.(*List); ok {
99+
newList := NewListSized(len(a.Items) + len(b.Items))
100+
copy(newList.Items, a.Items)
101+
copy(newList.Items[len(b.Items):], b.Items)
102+
return newList
103+
}
104+
return NotImplemented
105+
}
106+
107+
func (a *List) M__radd__(other Object) Object {
108+
if b, ok := other.(*List); ok {
109+
return b.M__add__(a)
110+
}
111+
return NotImplemented
112+
}
113+
114+
func (a *List) M__iadd__(other Object) Object {
115+
if b, ok := other.(*List); ok {
116+
a.Extend(b.Items)
117+
return a
118+
}
119+
return NotImplemented
120+
}
121+
122+
func (l *List) M__mul__(other Object) Object {
123+
if b, ok := convertToInt(other); ok {
124+
m := len(l.Items)
125+
n := int(b) * m
126+
newList := NewListSized(n)
127+
for i := 0; i < n; i += m {
128+
copy(newList.Items[i:i+m], l.Items)
129+
}
130+
return newList
131+
}
132+
return NotImplemented
133+
}
134+
135+
func (a *List) M__rmul__(other Object) Object {
136+
return a.M__mul__(other)
137+
}
138+
139+
func (a *List) M__imul__(other Object) Object {
140+
return a.M__mul__(other)
141+
}
142+
97143
// Check interface is satisfied
144+
var _ sequenceArithmetic = (*List)(nil)
145+
var _ I__len__ = (*List)(nil)
98146
var _ I__len__ = (*List)(nil)
99147
var _ I__bool__ = (*List)(nil)
100148
var _ I__iter__ = (*List)(nil)

py/py.go

+10
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,16 @@ type conversionBetweenTypes interface {
967967
I__round__
968968
}
969969

970+
// String, Tuple, List should statisfy this
971+
type sequenceArithmetic interface {
972+
I__add__
973+
I__mul__
974+
I__radd__
975+
I__rmul__
976+
I__iadd__
977+
I__imul__
978+
}
979+
970980
// FIXME everything should statisfy this ?
971981
// Make a basics interface
972982
// I__bool__

py/string.go

+38
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,44 @@ func (s String) M__len__() Object {
4545
return Int(utf8.RuneCountInString(string(s)))
4646
}
4747

48+
func (a String) M__add__(other Object) Object {
49+
if b, ok := other.(String); ok {
50+
return a + b
51+
}
52+
return NotImplemented
53+
}
54+
55+
func (a String) M__radd__(other Object) Object {
56+
if b, ok := other.(String); ok {
57+
return b + a
58+
}
59+
return NotImplemented
60+
}
61+
62+
func (a String) M__iadd__(other Object) Object {
63+
return a.M__add__(other)
64+
}
65+
66+
func (a String) M__mul__(other Object) Object {
67+
if b, ok := convertToInt(other); ok {
68+
newString := String("")
69+
for i := 0; i < int(b); i++ {
70+
newString += a
71+
}
72+
return newString
73+
}
74+
return NotImplemented
75+
}
76+
77+
func (a String) M__rmul__(other Object) Object {
78+
return a.M__mul__(other)
79+
}
80+
81+
func (a String) M__imul__(other Object) Object {
82+
return a.M__mul__(other)
83+
}
84+
4885
// Check interface is satisfied
86+
var _ sequenceArithmetic = String("")
4987
var _ I__len__ = String("")
5088
var _ I__bool__ = String("")

py/tuple.go

+43
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,50 @@ func (t Tuple) M__getitem__(key Object) Object {
4444
return t[i]
4545
}
4646

47+
func (a Tuple) M__add__(other Object) Object {
48+
if b, ok := other.(Tuple); ok {
49+
newTuple := make(Tuple, len(a)+len(b))
50+
copy(newTuple, a)
51+
copy(newTuple[len(b):], b)
52+
return newTuple
53+
}
54+
return NotImplemented
55+
}
56+
57+
func (a Tuple) M__radd__(other Object) Object {
58+
if b, ok := other.(Tuple); ok {
59+
return b.M__add__(a)
60+
}
61+
return NotImplemented
62+
}
63+
64+
func (a Tuple) M__iadd__(other Object) Object {
65+
return a.M__add__(other)
66+
}
67+
68+
func (l Tuple) M__mul__(other Object) Object {
69+
if b, ok := convertToInt(other); ok {
70+
m := len(l)
71+
n := int(b) * m
72+
newTuple := make(Tuple, n)
73+
for i := 0; i < n; i += m {
74+
copy(newTuple[i:i+m], l)
75+
}
76+
return newTuple
77+
}
78+
return NotImplemented
79+
}
80+
81+
func (a Tuple) M__rmul__(other Object) Object {
82+
return a.M__mul__(other)
83+
}
84+
85+
func (a Tuple) M__imul__(other Object) Object {
86+
return a.M__mul__(other)
87+
}
88+
4789
// Check interface is satisfied
90+
var _ sequenceArithmetic = Tuple(nil)
4891
var _ I__len__ = Tuple(nil)
4992
var _ I__bool__ = Tuple(nil)
5093
var _ I__iter__ = Tuple(nil)

0 commit comments

Comments
 (0)