fix builtin signatures

This commit is contained in:
Neemek 2026-07-11 11:09:26 +02:00
parent 5c336c7dec
commit f41ada6770
Signed by: neemek
GPG key ID: 84FFE4D7D40AB25E
2 changed files with 42 additions and 10 deletions

View file

@ -357,6 +357,26 @@ func (s *CompositeSignature) String() string {
return fmt.Sprintf("%s|%s", s.A, s.B) return fmt.Sprintf("%s|%s", s.A, s.B)
} }
func quickComposite(a ...TypeSignature) TypeSignature {
switch len(a) {
case 0:
panic("quick composite: empty array")
case 1:
return a[0]
}
s := a[0]
for i := 1; i < len(a); i++ {
v := a[i]
s = &CompositeSignature{
A: s,
B: v,
}
}
return s
}
type InnerSignature struct{} type InnerSignature struct{}
func (*InnerSignature) Type() Type { func (*InnerSignature) Type() Type {

View file

@ -549,7 +549,13 @@ var DefaultGlobals = map[string]Value{
"int": &BuiltinFunctionValue{ "int": &BuiltinFunctionValue{
"int", "int",
&FunctionSignature{ &FunctionSignature{
[]TypeSignature{&AnySignature{}}, []TypeSignature{
quickComposite(
&IntegerSignature{},
&FloatSignature{},
&StringSignature{},
),
},
&CompositeSignature{ &CompositeSignature{
&IntegerSignature{}, &IntegerSignature{},
&NilSignature{}, &NilSignature{},
@ -570,7 +576,7 @@ var DefaultGlobals = map[string]Value{
return &IntegerValue{n}, nil return &IntegerValue{n}, nil
default: default:
return nil, errors.New(fmt.Sprintf("%s cannot become an integer", v)) return nil, errors.New(fmt.Sprintf("%s cannot become an integer (undefined)", v))
} }
}, },
nil, nil,
@ -579,19 +585,25 @@ var DefaultGlobals = map[string]Value{
"float": &BuiltinFunctionValue{ "float": &BuiltinFunctionValue{
"float", "float",
&FunctionSignature{ &FunctionSignature{
[]TypeSignature{&AnySignature{}}, []TypeSignature{
&CompositeSignature{ quickComposite(
&FloatSignature{},
&IntegerSignature{},
&StringSignature{},
),
},
quickComposite(
&FloatSignature{}, &FloatSignature{},
&NilSignature{}, &NilSignature{},
}, ),
}, },
func(vm *VM, _ Value, args []Value) (Value, error) { func(vm *VM, _ Value, args []Value) (Value, error) {
switch v := args[0].(type) { switch v := args[0].(type) {
case *IntegerValue: case *IntegerValue:
n, _ := v.Number.Float64() n, _ := v.Number.Float64()
return &FloatValue{n}, nil // this might need to clone the value instead return &FloatValue{n}, nil
case *FloatValue: case *FloatValue:
return &FloatValue{v.Number}, nil return v.Clone(), nil
case *StringValue: case *StringValue:
num, err := strconv.ParseFloat(v.Text, FloatSize) num, err := strconv.ParseFloat(v.Text, FloatSize)
if err != nil { if err != nil {
@ -600,7 +612,7 @@ var DefaultGlobals = map[string]Value{
return &FloatValue{num}, nil return &FloatValue{num}, nil
default: default:
return nil, errors.New(fmt.Sprintf("%s cannot become an integer", v)) return nil, errors.New(fmt.Sprintf("%s cannot become an integer (undefined)", v))
} }
}, },
nil, nil,
@ -660,12 +672,12 @@ var DefaultGlobals = map[string]Value{
"roundd": &BuiltinFunctionValue{ "roundd": &BuiltinFunctionValue{
"roundd", "roundd",
&FunctionSignature{ &FunctionSignature{
[]TypeSignature{&FloatSignature{}, &FloatSignature{}}, []TypeSignature{&FloatSignature{}, &IntegerSignature{}},
&FloatSignature{}, &FloatSignature{},
}, },
func(vm *VM, this Value, args []Value) (Value, error) { func(vm *VM, this Value, args []Value) (Value, error) {
x := args[0].(*FloatValue).Number x := args[0].(*FloatValue).Number
decimals := args[1].(*FloatValue).Number decimals, _ := args[1].(*IntegerValue).Number.Float64()
multiplier := math.Pow(10, decimals) multiplier := math.Pow(10, decimals)
return &FloatValue{math.Round(x*multiplier) / multiplier}, nil return &FloatValue{math.Round(x*multiplier) / multiplier}, nil
}, },