summary refs log tree commit diff
path: root/services/irc/gamja.nix
AgeCommit message (Collapse)Author
2025-02-12Listen only on tailnet address for new internal rnrd.fyi sitesMel
Signed-off-by: Mel <mel@rnrd.eu>
2025-02-12Move tailnet internal sites to their own rnrd.fyi subdomainsMel
Signed-off-by: Mel <mel@rnrd.eu>
2024-12-26Pull out web configuration from specific machine modulesMel
Signed-off-by: Mel <einebeere@gmail.com>
2024-11-20Add favicon to gamja siteMel
Signed-off-by: Mel <einebeere@gmail.com>
id='n70' href='#n70'>70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
package vm

import (
	"jinx/pkg/lang/vm/code"
	"jinx/pkg/lang/vm/value"
)

func (vm *VM) createCoreNullType() value.Type {
	return value.Type{
		Kind: value.NullType,
	}
}

func (vm *VM) createCoreIntType() value.Type {
	return value.Type{
		Kind: value.IntType,
	}
}

func (vm *VM) createCoreFloatType() value.Type {
	return value.Type{
		Kind: value.FloatType,
	}
}

func (vm *VM) createCoreStringType() value.Type {
	return value.Type{
		Kind: value.StringType,
	}
}

func (vm *VM) createCoreBoolType() value.Type {
	return value.Type{
		Kind: value.BoolType,
	}
}

func (vm *VM) createCoreArrayType() value.Type {
	return value.Type{
		Kind: value.ArrayType,
		Methods: map[string]value.FunctionData{
			"length": makeCoreFn(vm.coreArrayLength, 0),
			"push": makeCoreFn(vm.coreArrayPush, 1),
		},
	}
}

func (vm *VM) createCoreFunctionType() value.Type {
	return value.Type{
		Kind: value.FunctionType,
	}
}

func (vm *VM) createCoreTypeRefType() value.Type {
	return value.Type{
		Kind: value.TypeRefType,
		Methods: map[string]value.FunctionData{
			"$add_method": makeCoreFn(vm.coreTypeRefIntrAddMethod, 2),
		},
	}
}

func (vm *VM) coreArrayLength(args []value.Value) (value.Value, error) {
	a, err := ensureTypeThis[value.ArrayData](vm, value.ArrayType)
	if err != nil {
		return value.Value{}, err
	}

	len, err := a.Len(vm.memory)
	if err != nil {
		return value.Value{}, err
	}
	res := value.NewInt(int64(len))
	return res, nil
}

func (vm *VM) coreArrayPush(args []value.Value) (value.Value, error) {
	a, err := ensureTypeThis[value.ArrayData](vm, value.ArrayType)
	if err != nil {
		return value.Value{}, err
	}

	return value.Value{}, a.Push(vm.memory, args[0])
}

func (vm *VM) coreTypeRefIntrAddMethod(args []value.Value) (value.Value, error) {
	ref, err := ensureTypeThis[value.TypeRefData](vm, value.TypeRefType)
	if err != nil {
		return value.Value{}, err
	}

	fn, err := ensureType[value.FunctionData](args[0], value.FunctionType)
	if err != nil {
		return value.Value{}, err
	}

	nameData, err := ensureType[value.StringData](args[1], value.StringType)
	if err != nil {
		return value.Value{}, err
	}
	name, err := nameData.RawString(vm.memory)
	if err != nil {
		return value.Value{}, err
	}

	return value.Value{}, ref.AddMethod(vm.memory, name, fn)
}

func ensureTypeThis[D value.Data](vm *VM, t value.TypeKind) (D, error) {
	this, err := vm.getThis()
	if err != nil {
		return *new(D), err
	}

	return ensureType[D](this, t)
}

func ensureType[D value.Data](val value.Value, t value.TypeKind) (D, error) {
	if val.Type() != t {
		return *new(D), ErrInvalidOperandType{
			Op: code.OpNop, // TODO: Add error not dependent on op.
			X:  val.Type(),
		}
	}

	return val.Data().(D), nil
}

func makeCoreFn(f value.NativeFunc, argCount uint) value.FunctionData {
	return value.NewNativeFunction(f, argCount).Data().(value.FunctionData)
}

func (vm *VM) getThis() (value.Value, error) {
	err := vm.execGetEnv(0)
	if err != nil {
		return value.Value{}, err
	}

	// Take it back!
	this, err := vm.popAndDrop()
	if err != nil {
		return value.Value{}, err
	}

	return this, nil
}