aboutsummaryrefslogtreecommitdiff
path: root/pkg/lang/vm
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/vm')
-rw-r--r--pkg/lang/vm/exec.go44
-rw-r--r--pkg/lang/vm/value/data.go11
2 files changed, 45 insertions, 10 deletions
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go
index 5a8eb05..353d8ac 100644
--- a/pkg/lang/vm/exec.go
+++ b/pkg/lang/vm/exec.go
@@ -208,17 +208,11 @@ func (vm *VM) execGetMember(name string) error {
if parent.Type() == value.TypeRefType {
ref := parent.Data().(value.TypeRefData)
- ptr := ref.TypeRef()
-
- cell, err := vm.getMemCell(ptr, mem.CellKindType, false)
+ ok, methodData, err := ref.GetMethod(vm.memory, name)
if err != nil {
return err
}
- typ := cell.(value.TypeCell).Get()
-
- methodData, ok := typ.GetMethod(name)
-
if !methodData.Env().IsNull() {
panic("methods with environments not implemented yet")
}
@@ -831,15 +825,45 @@ func (vm *VM) execCall(argCount uint) error {
return err
}
- if f.Type() != value.FunctionType {
+ var fn value.FunctionData
+ // Constructor call
+ if f.Type() == value.TypeRefType {
+ t := f.Data().(value.TypeRefData)
+ ok, initMethod, err := t.GetMethod(vm.memory, "$init")
+ if err != nil {
+ return err
+ }
+
+ if !ok {
+ panic("constructor not found on type")
+ }
+
+ // TODO: Very unsure about this, it's duplicated from execGetMember, probably need to refactor.
+ if f.Outlet().IsNull() {
+ outletPtr, err := vm.memory.Allocate(mem.CellKindOutlet)
+ if err != nil {
+ return err
+ }
+ f = f.WithOutlet(outletPtr)
+ }
+
+ newEnv := value.NewEnv()
+ newEnv.Add(0, f.Outlet())
+ envPtr, err := newEnv.Allocate(vm.memory)
+ if err != nil {
+ return err
+ }
+
+ fn = initMethod.WithEnv(envPtr)
+ } else if f.Type() == value.FunctionType {
+ fn = f.Data().(value.FunctionData)
+ } else {
return ErrInvalidOperandType{
Op: code.OpCall,
X: f.Type(),
}
}
- fn := f.Data().(value.FunctionData)
-
if argCount != fn.Args() {
return ErrWrongNumberOfArguments{
Got: argCount,
diff --git a/pkg/lang/vm/value/data.go b/pkg/lang/vm/value/data.go
index 6c3d762..6ec7be9 100644
--- a/pkg/lang/vm/value/data.go
+++ b/pkg/lang/vm/value/data.go
@@ -180,6 +180,17 @@ func (t TypeRefData) TypeRef() mem.Ptr {
return t.typeRef
}
+func (t TypeRefData) GetMethod(m mem.Mem, name string) (bool, FunctionData, error) {
+ cell, err := m.Get(t.typeRef)
+ if err != nil {
+ return false, FunctionData{}, err
+ }
+
+ typ := cell.(TypeCell).Get()
+ method, ok := typ.Methods[name]
+ return ok, method, nil
+}
+
func (t TypeRefData) AddMethod(m mem.Mem, name string, method FunctionData) error {
cell, err := m.Get(t.typeRef)
if err != nil {