Skip to content

Commit 0d176ae

Browse files
authored
Add superclass chain traversal (#134)
* add superclass chain traversal * whitespace
1 parent ab68701 commit 0d176ae

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

evaluator/evaluator_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,71 @@ func TestTraitMethodLookup(t *testing.T) {
307307
}
308308
}
309309

310+
func TestInheritedProperties(t *testing.T) {
311+
tests := []struct {
312+
name string
313+
input string
314+
expected int64
315+
}{
316+
{
317+
name: "access parent class property",
318+
input: `
319+
class Animal {
320+
species = 42
321+
}
322+
323+
class Dog extends Animal {
324+
}
325+
326+
d = Dog.new()
327+
d.species
328+
`,
329+
expected: 42,
330+
},
331+
{
332+
name: "access grandparent class property",
333+
input: `
334+
class Animal {
335+
legs = 4
336+
}
337+
338+
class Mammal extends Animal {
339+
}
340+
341+
class Dog extends Mammal {
342+
}
343+
344+
d = Dog.new()
345+
d.legs
346+
`,
347+
expected: 4,
348+
},
349+
{
350+
name: "child property overrides parent",
351+
input: `
352+
class Animal {
353+
sound = 1
354+
}
355+
356+
class Dog extends Animal {
357+
sound = 2
358+
}
359+
360+
d = Dog.new()
361+
d.sound
362+
`,
363+
expected: 2,
364+
},
365+
}
366+
367+
for _, tt := range tests {
368+
t.Run(tt.name, func(t *testing.T) {
369+
result := evaluate(tt.input)
370+
isNumberObject(t, result, tt.expected)
371+
})
372+
}
373+
}
374+
310375
// =============================================================================
311376
// Helper functions
312377

evaluator/property.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ func evaluateInstanceProperty(left object.Object, node *ast.Property) object.Obj
5959
return val
6060
}
6161

62+
class := instance.Class.Super
63+
64+
for class != nil {
65+
if class.Environment.Has(property.Value) {
66+
val, _ = class.Environment.Get(property.Value)
67+
68+
return val
69+
}
70+
71+
class = class.Super
72+
}
73+
6274
for _, trait := range instance.Class.Traits {
6375
if trait.Environment.Has(property.Value) {
6476
val, _ = trait.Environment.Get(property.Value)

0 commit comments

Comments
 (0)