|
@@ -416,6 +416,100 @@ func exit(vm *VM, val ...Value) [] Value {
|
|
|
return Ok()
|
|
|
}
|
|
|
|
|
|
+type Door struct {
|
|
|
+ name string
|
|
|
+ locked bool
|
|
|
+ opened bool
|
|
|
+}
|
|
|
+
|
|
|
+// Implement callable ...
|
|
|
+func (door * Door) Position() *Position {
|
|
|
+ return &Position{"builtin.go", 427, 8}
|
|
|
+}
|
|
|
+
|
|
|
+type ValueCallable interface {
|
|
|
+ Callable
|
|
|
+ Value
|
|
|
+}
|
|
|
+
|
|
|
+func Redispatch(from ValueCallable, vm *VM, args...Value) []Value {
|
|
|
+ if len(args) < 1 {
|
|
|
+ return EmptyValueArray()
|
|
|
+ }
|
|
|
+ var word WordValue
|
|
|
+ _, err := ParseOptArgs(args, 1, &word)
|
|
|
+ if err != nil {
|
|
|
+ return Fail(err)
|
|
|
+ }
|
|
|
+ args[0] = from
|
|
|
+ return vm.CallNamed(string(word), args...)
|
|
|
+}
|
|
|
+
|
|
|
+func (door * Door) Call(vm *VM, args...Value) []Value {
|
|
|
+ return Redispatch(door, vm, args...)
|
|
|
+}
|
|
|
+
|
|
|
+var doorSignature = NewSignature(WordTypeValue)
|
|
|
+
|
|
|
+func (door * Door) Signature() *Signature {
|
|
|
+ return &doorSignature
|
|
|
+}
|
|
|
+
|
|
|
+var _ Callable = &Door{}
|
|
|
+
|
|
|
+const DoorType = TypeValue("Door")
|
|
|
+
|
|
|
+func (door * Door) String() string {
|
|
|
+ return fmt.Sprintf("Door: %s %v %v", door.name, door.locked, door.opened)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (*Door) Type() TypeValue {
|
|
|
+ return DoorType
|
|
|
+}
|
|
|
+
|
|
|
+func (from * Door) Convert(to interface{}) error {
|
|
|
+ switch toPtr := to.(type) {
|
|
|
+ case **Door:
|
|
|
+ (*toPtr) = from
|
|
|
+ case *Door:
|
|
|
+ (*toPtr) = *from
|
|
|
+ case *Value:
|
|
|
+ (*toPtr) = from
|
|
|
+ default:
|
|
|
+ return NewErrorValuef("Cannot convert DoorValue value %v to %v", from, to)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func door(vm *VM, val ...Value) [] Value {
|
|
|
+ var name string
|
|
|
+ var locked bool
|
|
|
+ _, err := ParseOptArgs(val, 1, &name, &locked)
|
|
|
+ if err != nil {
|
|
|
+ return Fail(err)
|
|
|
+ }
|
|
|
+ return Ok(&Door{name: name, locked: locked, opened:false})
|
|
|
+}
|
|
|
+
|
|
|
+func (door * Door) Open() {
|
|
|
+ door.opened = true
|
|
|
+}
|
|
|
+
|
|
|
+func openDoor(vm *VM, val ...Value) [] Value {
|
|
|
+ var door *Door
|
|
|
+ _, err := ParseArgs(val, &door)
|
|
|
+ if err != nil {
|
|
|
+ return Fail(err)
|
|
|
+ }
|
|
|
+ if door == nil {
|
|
|
+ return Fail(NewErrorValuef("Door may not be nil."))
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Printf("Door: %v %s", door, door)
|
|
|
+ door.Open()
|
|
|
+ return Ok(door)
|
|
|
+}
|
|
|
|
|
|
func (vm *VM) RegisterBuiltins() {
|
|
|
vm.RegisterBuiltinWithHelp("addi", addi, `[Int Int] -> Int: adds two integers together`)
|
|
@@ -450,6 +544,10 @@ func (vm *VM) RegisterBuiltins() {
|
|
|
vm.RegisterBuiltin("help", help)
|
|
|
vm.RegisterBuiltin("explain", explain)
|
|
|
vm.RegisterBuiltin("exit", exit)
|
|
|
+ vm.RegisterBuiltin("door", door)
|
|
|
+ vm.RegisterBuiltin("openDoor", openDoor)
|
|
|
+ vm.Register("Door", DoorType)
|
|
|
+ vm.AddOverloads("open", Over("openDoor", 0, DoorType))
|
|
|
|
|
|
vm.AddOverloads("mul",
|
|
|
Over("mulf", 0, FloatTypeValue, FloatTypeValue),
|