add basic records

This commit is contained in:
Neemek 2026-07-15 21:48:30 +02:00
parent ca0031431d
commit 19011e67da
Signed by: neemek
GPG key ID: 84FFE4D7D40AB25E
2 changed files with 113 additions and 3 deletions

View file

@ -21,6 +21,7 @@ const (
TypeComposite TypeComposite
TypeInner TypeInner
TypeNamed TypeNamed
TypeRecord
) )
func (t Type) String() string { func (t Type) String() string {
@ -521,3 +522,56 @@ func (s *NamedSignature) Equal(t TypeSignature) bool {
func (s *NamedSignature) String() string { func (s *NamedSignature) String() string {
return s.Name return s.Name
} }
type RecordSignature struct {
Entries map[string]TypeSignature
}
func (*RecordSignature) Type() Type {
return TypeRecord
}
func (s *RecordSignature) Contains(t TypeSignature) bool {
if t.Type() != TypeRecord {
return false
}
rs := t.(*RecordSignature)
/*
// not quite sure about this one
if len(s.Entries) != len(rs.Entries) {
return false
}
*/
for k, v := range s.Entries {
is, ok := rs.Entries[k]
if !ok {
return false
}
if !v.Contains(is) {
return false
}
}
return true
}
func (s *RecordSignature) Equal(t TypeSignature) bool {
return s.Contains(t) && t.Contains(s)
}
func (s *RecordSignature) String() string {
b := strings.Builder{}
b.WriteString("(")
for name, kind := range s.Entries {
b.WriteString(fmt.Sprintf("%s: %s, ", name, kind))
}
b.WriteString(")")
return b.String()
}

View file

@ -22,7 +22,7 @@ const (
ObjectValueType ObjectValueType
FunctionValueType FunctionValueType
BuiltinFunctionValueType BuiltinFunctionValueType
VariableValueType RecordValueType
) )
func (v ValueType) String() string { func (v ValueType) String() string {
@ -47,8 +47,8 @@ func (v ValueType) String() string {
return "function" return "function"
case BuiltinFunctionValueType: case BuiltinFunctionValueType:
return "builtin function" return "builtin function"
case VariableValueType: case RecordValueType:
return "variable" return "record"
} }
return "undefined" return "undefined"
@ -767,3 +767,59 @@ func (v *BuiltinFunctionValue) Clone() Value {
v.Constant, v.Constant,
} }
} }
type RecordValue struct {
Entries map[string]Value
}
func (v *RecordValue) Type() ValueType {
return RecordValueType
}
func (v *RecordValue) String() string {
return ""
}
func (v *RecordValue) DebugString() string {
return v.String()
}
func (v *RecordValue) Clone() Value {
return &RecordValue{
v.Entries,
}
}
func (v *RecordValue) Equals(other Value) bool {
if other.Type() != RecordValueType {
return false
}
r := other.(*RecordValue)
if len(r.Entries) != len(v.Entries) {
return false
}
for key, val := range v.Entries {
oth, ok := r.Entries[key]
if !ok {
return false
}
if !val.Equals(oth) {
return false
}
}
return true
}
func (v *RecordValue) Get(key string) (Value, error) {
val, ok := v.Entries[key]
if !ok {
return nil, errors.New(fmt.Sprintf("record has no property \"%s\"", key))
}
return val, nil
}