about summary refs log tree commit diff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/lang/vm/exec.go13
-rw-r--r--pkg/lang/vm/value/data.go20
-rw-r--r--pkg/lang/vm/value/value.go4
3 files changed, 33 insertions, 4 deletions
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go
index bd4cdf5..10ac604 100644
--- a/pkg/lang/vm/exec.go
+++ b/pkg/lang/vm/exec.go
@@ -447,6 +447,19 @@ func (vm *VM) execCall() error {
 		return err
 	}
 
+	if fn.Native() != nil {
+		// TODO: Arguments
+		val, err := fn.Native()([]value.Value{})
+		if err != nil {
+			return err
+		}
+
+		if !val.IsEmpty() {
+			vm.stack.Push(val)
+		}
+
+		return nil
+	}
 	vm.pc = fn.Pc()
 
 	return nil
diff --git a/pkg/lang/vm/value/data.go b/pkg/lang/vm/value/data.go
index 4e39bc8..c0e5e9a 100644
--- a/pkg/lang/vm/value/data.go
+++ b/pkg/lang/vm/value/data.go
@@ -115,10 +115,13 @@ func (a ArrayData) Push(m mem.Mem, v Value) error {
 type NullData struct{}
 
 type FunctionData struct {
-	pc  int
-	env mem.Ptr
+	pc     int
+	env    mem.Ptr
+	native NativeFunc
 }
 
+type NativeFunc func([]Value) (Value, error)
+
 func (f FunctionData) Pc() int {
 	return f.pc
 }
@@ -127,12 +130,21 @@ func (f FunctionData) Env() mem.Ptr {
 	return f.env
 }
 
+func (f FunctionData) Native() NativeFunc {
+	return f.native
+}
+
 func (f FunctionData) WithEnv(env mem.Ptr) FunctionData {
-	return FunctionData{pc: f.pc, env: env}
+	return FunctionData{pc: f.pc, env: env, native: f.native}
 }
 
 func (f FunctionData) String(_ mem.Mem) (string, error) {
-	return fmt.Sprintf("<fn %d>", f.pc), nil
+	if f.native != nil {
+		return "<fn native>", nil
+	} else {
+		return fmt.Sprintf("<fn %d>", f.pc), nil
+	}
+}
 }
 
 type ObjectData struct{} // TODO
diff --git a/pkg/lang/vm/value/value.go b/pkg/lang/vm/value/value.go
index a2909ba..cce0f1b 100644
--- a/pkg/lang/vm/value/value.go
+++ b/pkg/lang/vm/value/value.go
@@ -85,6 +85,10 @@ func (v Value) WithOutlet(outlet mem.Ptr) Value {
 	return Value{t: v.t, d: v.d, outlet: outlet}
 }
 
+func (v Value) IsEmpty() bool {
+	return v.t == mem.NullPtr
+}
+
 func (v Value) Clone(m mem.Mem) Value {
 	if v.t.Kind == StringType {
 		str := v.d.(StringData)