lox-go/runtime/types.go
2025-06-08 16:03:02 -04:00

101 lines
1.6 KiB
Go

package runtime
import "fmt"
//go:generate stringer -type LoxType -trimprefix LoxType
type LoxType int
const (
LoxTypeString LoxType = iota
LoxTypeNumber
LoxTypeBoolean
LoxTypeNil
LoxTypeUndefined
)
type LoxValue struct {
raw any
}
func (v *LoxValue) Type() LoxType {
switch v.raw.(type) {
case string:
return LoxTypeString
case float64:
return LoxTypeNumber
case bool:
return LoxTypeBoolean
case nil:
return LoxTypeNil
default:
return LoxTypeUndefined
}
}
func (v *LoxValue) Debug() string {
return fmt.Sprintf("%+v", v.raw)
}
func (v *LoxValue) String() string {
if string, ok := v.raw.(string); ok {
return string
}
return ""
}
func (v *LoxValue) Number() float64 {
if number, ok := v.raw.(float64); ok {
return number
}
return 0.0
}
func (v *LoxValue) IsString() bool {
return v.Type() == LoxTypeString
}
func (v *LoxValue) IsNumber() bool {
return v.Type() == LoxTypeNumber
}
func (v *LoxValue) IsTruthy() bool {
switch v.Type() {
case LoxTypeBoolean:
b, ok := v.raw.(bool)
return ok && b
case LoxTypeNumber, LoxTypeString:
return true
default:
return false
}
}
func (v *LoxValue) IsNil() bool {
return v.Type() == LoxTypeNil
}
func (v *LoxValue) IsUndefined() bool {
return v.Type() == LoxTypeUndefined
}
func (v *LoxValue) Equals(other *LoxValue) bool {
return AreEqual(v, other)
}
func Value(v any) *LoxValue {
return &LoxValue{v}
}
func AreEqual(a, b *LoxValue) bool {
typeA := a.Type()
typeB := b.Type()
if typeA != typeB {
return false
}
return a.raw == b.raw
}
func AreEqualValue(a, b *LoxValue) *LoxValue {
return Value(AreEqual(a, b))
}