diff --git a/src/array.go b/src/array.go index e8b9697..3df7f2c 100644 --- a/src/array.go +++ b/src/array.go @@ -597,6 +597,32 @@ func ArArray(arr []any) ArObject { return false, ArErr{} }, } + val.obj["__NotContains__"] = builtinFunc{ + "__NotContains__", + func(args ...any) (any, ArErr) { + if len(args) != 1 { + return nil, ArErr{ + TYPE: "TypeError", + message: "missing argument", + EXISTS: true, + } + } + for _, v := range arr { + res, err := runOperation(operationType{ + operation: 9, + value1: v, + value2: args[0], + }, stack{}, 0) + if err.EXISTS { + return nil, err + } + if anyToBool(res) { + return false, ArErr{} + } + } + return true, ArErr{} + }, + } val.obj["__Boolean__"] = builtinFunc{ "__Boolean__", func(args ...any) (any, ArErr) { diff --git a/src/buffer.go b/src/buffer.go index 47ffab5..bad094e 100644 --- a/src/buffer.go +++ b/src/buffer.go @@ -139,7 +139,7 @@ func ArBuffer(buf []byte) ArObject { default: return nil, ArErr{ TYPE: "TypeError", - message: "expected string or []byte, got " + typeof(x), + message: "expected string or buffer, got " + typeof(x), EXISTS: true, } } @@ -190,5 +190,170 @@ func ArBuffer(buf []byte) ArObject { } }, } + obj.obj["append"] = builtinFunc{ + "append", + func(a ...any) (any, ArErr) { + if len(a) != 1 { + return nil, ArErr{ + TYPE: "TypeError", + message: "expected 1 argument, got " + fmt.Sprint(len(a)), + EXISTS: true, + } + } + a[0] = ArValidToAny(a[0]) + switch x := a[0].(type) { + case number: + if x.Denom().Cmp(one.Denom()) != 0 { + return nil, ArErr{ + TYPE: "TypeError", + message: "Cannot convert non-integer to byte", + EXISTS: true, + } + } + buf = append(buf, byte(x.Num().Int64())) + case string: + buf = append(buf, []byte(x)...) + case []byte: + buf = append(buf, x...) + case []any: + for _, v := range x { + switch y := v.(type) { + case number: + if y.Denom().Cmp(one.Denom()) != 0 { + return nil, ArErr{ + TYPE: "TypeError", + message: "Cannot convert non-integer to byte", + EXISTS: true, + } + } + buf = append(buf, byte(y.Num().Int64())) + default: + return nil, ArErr{ + TYPE: "TypeError", + message: "Cannot convert " + typeof(v) + " to byte", + EXISTS: true, + } + } + } + default: + return nil, ArErr{ + TYPE: "TypeError", + message: "expected string, buffer or array, got " + typeof(x), + EXISTS: true, + } + } + obj.obj["__value__"] = buf + obj.obj["length"] = newNumber().SetInt64(int64(len(buf))) + return obj, ArErr{} + }, + } + obj.obj["insert"] = builtinFunc{ + "insert", + func(a ...any) (any, ArErr) { + if len(a) != 2 { + return nil, ArErr{ + TYPE: "TypeError", + message: "expected 2 arguments, got " + fmt.Sprint(len(a)), + EXISTS: true, + } + } + poss := ArValidToAny(a[0]) + values := ArValidToAny(a[1]) + if typeof(poss) != "number" { + return nil, ArErr{ + TYPE: "TypeError", + message: "expected number, got " + typeof(poss), + EXISTS: true, + } + } + pos := poss.(number) + if pos.Denom().Cmp(one.Denom()) != 0 { + return nil, ArErr{ + TYPE: "TypeError", + message: "position must be an integer", + EXISTS: true, + } + } + posNum := pos.Num().Int64() + switch x := values.(type) { + case number: + if x.Denom().Cmp(one.Denom()) != 0 { + return nil, ArErr{ + TYPE: "TypeError", + message: "Cannot convert non-integer to byte", + EXISTS: true, + } + } + buf = append(buf[:posNum], append([]byte{byte(x.Num().Int64())}, buf[posNum:]...)...) + case string: + buf = append(buf[:posNum], append([]byte(x), buf[posNum:]...)...) + case []byte: + buf = append(buf[:posNum], append(x, buf[posNum:]...)...) + case []any: + for _, v := range x { + switch y := v.(type) { + case number: + if y.Denom().Cmp(one.Denom()) != 0 { + return nil, ArErr{ + TYPE: "TypeError", + message: "Cannot convert non-integer to byte", + EXISTS: true, + } + } + buf = append(buf[:posNum], append([]byte{byte(y.Num().Int64())}, buf[posNum:]...)...) + default: + return nil, ArErr{ + TYPE: "TypeError", + message: "Cannot convert " + typeof(v) + " to byte", + EXISTS: true, + } + } + } + default: + return nil, ArErr{ + TYPE: "TypeError", + message: "expected string or buffer, got " + typeof(x), + EXISTS: true, + } + } + obj.obj["__value__"] = buf + obj.obj["length"] = newNumber().SetInt64(int64(len(buf))) + return obj, ArErr{} + }, + } + obj.obj["remove"] = builtinFunc{ + "remove", + func(a ...any) (any, ArErr) { + if len(a) != 1 { + return nil, ArErr{ + TYPE: "TypeError", + message: "expected 1 argument, got " + fmt.Sprint(len(a)), + EXISTS: true, + } + } + poss := ArValidToAny(a[0]) + if typeof(poss) != "number" { + return nil, ArErr{ + TYPE: "TypeError", + message: "expected number, got " + typeof(poss), + EXISTS: true, + } + } + pos := poss.(number) + if pos.Denom().Cmp(one.Denom()) != 0 { + return nil, ArErr{ + TYPE: "TypeError", + message: "position must be an integer", + EXISTS: true, + } + } + posNum := pos.Num().Int64() + buf = append(buf[:posNum], buf[posNum+1:]...) + obj.obj["__value__"] = buf + obj.obj["length"] = newNumber().SetInt64(int64(len(buf))) + return obj, ArErr{} + }, + } + return obj } diff --git a/src/string.go b/src/string.go index 700181f..4864cef 100644 --- a/src/string.go +++ b/src/string.go @@ -565,7 +565,7 @@ func ArString(str string) ArObject { if typeof(a[0]) != "string" { a[0] = anyToArgon(a[0], false, false, 3, 0, false, 0) } - return strings.Join([]string{str, a[0].(string)}, ""), ArErr{} + return str + a[0].(string), ArErr{} }} obj.obj["__PostAdd__"] = builtinFunc{ "__PostAdd__", @@ -577,7 +577,7 @@ func ArString(str string) ArObject { if typeof(a[0]) != "string" { a[0] = anyToArgon(a[0], false, false, 3, 0, false, 0) } - return strings.Join([]string{a[0].(string), str}, ""), ArErr{} + return a[0].(string) + str, ArErr{} }} obj.obj["__Multiply__"] = builtinFunc{ "__Multiply__", @@ -597,6 +597,18 @@ func ArString(str string) ArObject { } return strings.Repeat(str, int(n.Num().Int64())), ArErr{} }} + obj.obj["__NotContains__"] = builtinFunc{ + "__NotContains__", + func(a ...any) (any, ArErr) { + if len(a) != 1 { + return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true} + } + if typeof(a[0]) != "string" { + return nil, ArErr{"TypeError", "cannot check if string contains " + typeof(a[0]), 0, "", "", true} + } + a[0] = ArValidToAny(a[0]) + return !strings.Contains(str, a[0].(string)), ArErr{} + }} obj.obj["__Contains__"] = builtinFunc{ "__Contains__", func(a ...any) (any, ArErr) {