diff --git a/evaluator/builtins.go b/evaluator/builtins.go index d6fffd6..f38a445 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -148,6 +148,36 @@ var builtins = map[string]*object.Builtin{ }, }, + "badilisha": { + Fn: func(args ...object.Object) object.Object { + if len(args) != 2 { + return newError("Samahani, badili inahitaji hoja 2, wewe umeweka %d", len(args)) + } + + value := args[0] + targetType := args[1] + + if targetType.Type() != object.STRING_OBJ { + return newError("Aina ya lengo lazima iwe neno") + } + + targetTypeStr := targetType.(*object.String).Value + + switch targetTypeStr { + case "NAMBA": + return convertToInteger(value) + case "DESIMALI": + return convertToFloat(value) + case "NENO": + return convertToString(value) + case "BOOLEAN": + return convertToBoolean(value) + default: + return newError("Aina isiyojulikana: %s", targetTypeStr) + } + }, + }, + // "jumla": { // Fn: func(args ...object.Object) object.Object { // if len(args) != 1 { diff --git a/evaluator/type.go b/evaluator/type.go new file mode 100644 index 0000000..43a3fe0 --- /dev/null +++ b/evaluator/type.go @@ -0,0 +1,72 @@ +package evaluator + +import ( + "strconv" + + "github.com/NuruProgramming/Nuru/object" +) + +func convertToInteger(obj object.Object) object.Object { + switch obj := obj.(type) { + case *object.Integer: + return obj + case *object.Float: + return &object.Integer{Value: int64(obj.Value)} + case *object.String: + i, err := strconv.ParseInt(obj.Value, 10, 64) + if err != nil { + return newError("Haiwezi kubadilisha '%s' kuwa NAMBA", obj.Value) + } + return &object.Integer{Value: i} + case *object.Boolean: + if obj.Value { + return &object.Integer{Value: 1} + } + return &object.Integer{Value: 0} + default: + return newError("Haiwezi kubadilisha %s kuwa NAMBA", obj.Type()) + } +} + +func convertToFloat(obj object.Object) object.Object { + switch obj := obj.(type) { + case *object.Float: + return obj + case *object.Integer: + return &object.Float{Value: float64(obj.Value)} + case *object.String: + f, err := strconv.ParseFloat(obj.Value, 64) + if err != nil { + return newError("Haiwezi kubadilisha '%s' kuwa DESIMALI", obj.Value) + } + return &object.Float{Value: f} + case *object.Boolean: + if obj.Value { + return &object.Float{Value: 1.0} + } + return &object.Float{Value: 0.0} + default: + return newError("Haiwezi kubadilisha %s kuwa DESIMALI", obj.Type()) + } +} + +func convertToString(obj object.Object) object.Object { + return &object.String{Value: obj.Inspect()} +} + +func convertToBoolean(obj object.Object) object.Object { + switch obj := obj.(type) { + case *object.Boolean: + return obj + case *object.Integer: + return &object.Boolean{Value: obj.Value != 0} + case *object.Float: + return &object.Boolean{Value: obj.Value != 0} + case *object.String: + return &object.Boolean{Value: len(obj.Value) > 0} + case *object.Null: + return &object.Boolean{Value: false} + default: + return &object.Boolean{Value: true} + } +}