1 Commits

6 changed files with 98 additions and 79 deletions

View File

@@ -80,7 +80,7 @@ func ArArray(arr []any) ArObject {
if typeof(a[0]) != "number" { if typeof(a[0]) != "number" {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "dex must be a number", message: "index must be a number",
EXISTS: true, EXISTS: true,
} }
} }

View File

@@ -48,26 +48,12 @@ func ArgonSqrt(a ...any) (any, ArErr) {
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes 1 argument", return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes 1 argument",
EXISTS: true} EXISTS: true}
} }
if typeof(a[0]) != "number" { if _, ok := a[0].(ArObject); !ok {
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes a number not a '" + typeof(a[0]) + "'", return nil, ArErr{TYPE: "Runtime Error", message: "can't sqrt type '" + typeof(a[0]) + "'",
EXISTS: true} EXISTS: true}
} }
if sqrt_method, ok := a[0].(ArObject).obj["__sqrt__"]; ok {
r := a[0].(number) return builtinCall(sqrt_method, []any{})
if r.Sign() < 0 {
return nil, ArErr{TYPE: "Runtime Error", message: "sqrt takes a positive number",
EXISTS: true}
} }
return nil, ArErr{TYPE: "Runtime Error", message: "can't sqrt type '" + typeof(a[0]) + "'"}
var x big.Float
x.SetPrec(30)
x.SetRat(r)
var s big.Float
s.SetPrec(15)
s.Sqrt(&x)
r, _ = s.Rat(nil)
return r, ArErr{}
} }

View File

@@ -11,7 +11,7 @@ func makeGlobal() ArObject {
vars["env"] = env vars["env"] = env
vars["term"] = ArTerm vars["term"] = ArTerm
vars["ArgonVersion"] = ArString(VERSION) vars["ArgonVersion"] = ArString(VERSION)
vars["ArgonVersionNumber"] = newNumber().SetInt64(VERSION_NUM) vars["ArgonVersionNumber"] = Number(VERSION_NUM)
vars["number"] = builtinFunc{"number", ArgonNumber} vars["number"] = builtinFunc{"number", ArgonNumber}
vars["string"] = builtinFunc{"string", ArgonString} vars["string"] = builtinFunc{"string", ArgonString}
vars["socket"] = Map(anymap{ vars["socket"] = Map(anymap{
@@ -65,12 +65,8 @@ func makeGlobal() ArObject {
} }
a[0] = ArValidToAny(a[0]) a[0] = ArValidToAny(a[0])
switch x := a[0].(type) { switch x := a[0].(type) {
case number: case int64:
if x.Denom().Cmp(_one_Rat.Denom()) != 0 { return ArString(fmt.Sprintf("%x", x)), ArErr{}
return nil, ArErr{TYPE: "Type Error", message: "Cannot convert non-integer to hex", EXISTS: true}
}
n := x.Num().Int64()
return ArString(fmt.Sprintf("%x", n)), ArErr{}
} }
return nil, ArErr{TYPE: "Type Error", message: "Cannot convert '" + typeof(a[0]) + "' to hex", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot convert '" + typeof(a[0]) + "' to hex", EXISTS: true}
}} }}
@@ -131,22 +127,21 @@ func makeGlobal() ArObject {
return nil, ArErr{TYPE: "round", message: "round takes 1 argument", return nil, ArErr{TYPE: "round", message: "round takes 1 argument",
EXISTS: true} EXISTS: true}
} }
precision := newNumber() var precision int64 = 0
if len(a) > 1 { if len(a) > 1 {
a[1] = ArValidToAny(a[1])
switch x := a[1].(type) { switch x := a[1].(type) {
case number: case int64:
if !x.IsInt() {
return nil, ArErr{TYPE: "Type Error", message: "Cannot round to '" + typeof(a[1]) + "'", EXISTS: true}
}
precision = x precision = x
default: default:
return nil, ArErr{TYPE: "Type Error", message: "Cannot round to '" + typeof(a[1]) + "'", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot round to '" + typeof(a[1]) + "'", EXISTS: true}
} }
} }
switch x := a[0].(type) { switch x := a[0].(type) {
case number: case ArObject:
return round(newNumber().Set(x), int(precision.Num().Int64())), ArErr{} if round_method, ok := x.obj["__round__"]; ok {
return builtinCall(round_method, []any{Number(precision)})
}
} }
return nil, ArErr{TYPE: "Type Error", message: "Cannot round '" + typeof(a[0]) + "'", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot round '" + typeof(a[0]) + "'", EXISTS: true}
}} }}
@@ -156,8 +151,10 @@ func makeGlobal() ArObject {
EXISTS: true} EXISTS: true}
} }
switch x := a[0].(type) { switch x := a[0].(type) {
case number: case ArObject:
return floor(x), ArErr{} if floor_method, ok := x.obj["__floor__"]; ok {
return builtinCall(floor_method, []any{})
}
} }
return nil, ArErr{TYPE: "Type Error", message: "Cannot floor '" + typeof(a[0]) + "'", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot floor '" + typeof(a[0]) + "'", EXISTS: true}
}} }}
@@ -166,10 +163,11 @@ func makeGlobal() ArObject {
return nil, ArErr{TYPE: "ceil", message: "ceil takes 1 argument", return nil, ArErr{TYPE: "ceil", message: "ceil takes 1 argument",
EXISTS: true} EXISTS: true}
} }
switch x := a[0].(type) { switch x := a[0].(type) {
case number: case ArObject:
return ceil(x), ArErr{} if ceil_method, ok := x.obj["__ceil__"]; ok {
return builtinCall(ceil_method, []any{})
}
} }
return nil, ArErr{TYPE: "Type Error", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot ceil '" + typeof(a[0]) + "'", EXISTS: true}
}} }}
@@ -198,8 +196,6 @@ func makeGlobal() ArObject {
EXISTS: true} EXISTS: true}
} }
switch x := a[0].(type) { switch x := a[0].(type) {
case number:
return ArString(x.String()), ArErr{}
case ArObject: case ArObject:
if callable, ok := x.obj["__fraction__"]; ok { if callable, ok := x.obj["__fraction__"]; ok {
resp, err := runCall( resp, err := runCall(
@@ -239,9 +235,11 @@ func makeGlobal() ArObject {
if len(a) == 0 { if len(a) == 0 {
os.Exit(0) os.Exit(0)
} }
a[0] = ArValidToAny(a[0])
switch x := a[0].(type) { switch x := a[0].(type) {
case number: case int64:
os.Exit(int(floor(x).Num().Int64())) os.Exit(int(x))
return nil, ArErr{}
} }
os.Exit(0) os.Exit(0)
return nil, ArErr{} return nil, ArErr{}
@@ -267,7 +265,7 @@ func makeGlobal() ArObject {
if len(x) != 1 { if len(x) != 1 {
return nil, ArErr{TYPE: "ord", message: "ord takes a string with only one character, got " + fmt.Sprint(len(a)), EXISTS: true} return nil, ArErr{TYPE: "ord", message: "ord takes a string with only one character, got " + fmt.Sprint(len(a)), EXISTS: true}
} }
return floor(newNumber().SetInt64(int64([]rune(x)[0]))), ArErr{} return Number(int64([]rune(x)[0])), ArErr{}
} }
return nil, ArErr{TYPE: "Type Error", message: "Cannot convert '" + typeof(a[0]) + "' to string", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot convert '" + typeof(a[0]) + "' to string", EXISTS: true}
}} }}
@@ -281,15 +279,27 @@ func makeGlobal() ArObject {
if len(x) == 0 { if len(x) == 0 {
return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true} return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true}
} }
var max number var max ArObject
for i, v := range x { for i, v := range x {
switch m := v.(type) { switch x := v.(type) {
case number: case ArObject:
if i == 0 { if i == 0 {
max = m max = x
} else { } else {
if m.Cmp(max) == 1 { compared, err := CompareObjects(max, x)
max = m
if err.EXISTS {
return nil, err
}
compared_int, Err := numberToInt64(compared)
if Err != nil {
return nil, ArErr{TYPE: "Type Error", message: Err.Error(), EXISTS: true}
}
if compared_int == 1 {
max = x
} }
} }
} }
@@ -308,15 +318,27 @@ func makeGlobal() ArObject {
if len(x) == 0 { if len(x) == 0 {
return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true} return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true}
} }
var max number var max ArObject
for i, v := range x { for i, v := range x {
switch m := v.(type) { switch x := v.(type) {
case number: case ArObject:
if i == 0 { if i == 0 {
max = m max = x
} else { } else {
if m.Cmp(max) == -1 { compared, err := CompareObjects(max, x)
max = m
if err.EXISTS {
return nil, err
}
compared_int, Err := numberToInt64(compared)
if Err != nil {
return nil, ArErr{TYPE: "Type Error", message: Err.Error(), EXISTS: true}
}
if compared_int == -1 {
max = x
} }
} }
} }

View File

@@ -153,11 +153,11 @@ func ArRead(args ...any) (any, ArErr) {
if typeof(args[0]) != "number" { if typeof(args[0]) != "number" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "buffer takes a number not type '" + typeof(args[0]) + "'", EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: "buffer takes a number not type '" + typeof(args[0]) + "'", EXISTS: true}
} }
size := args[0].(number) size, err := numberToInt64(args[0].(ArObject))
if size.Denom().Int64() != 1 { if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "buffer takes an integer not type '" + typeof(args[0]) + "'", EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
} }
buf := make([]byte, size.Num().Int64()) buf := make([]byte, size)
n, err := file.Read(buf) n, err := file.Read(buf)
if err != nil { if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
@@ -177,11 +177,11 @@ func ArRead(args ...any) (any, ArErr) {
if typeof(args[0]) != "number" { if typeof(args[0]) != "number" {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes a number not type '" + typeof(args[0]) + "'", EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes a number not type '" + typeof(args[0]) + "'", EXISTS: true}
} }
offset := args[0].(number) offset, Err := numberToInt64(args[0].(ArObject))
if offset.Denom().Int64() != 1 { if Err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes an integer not type '" + typeof(args[0]) + "'", EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: Err.Error(), EXISTS: true}
} }
_, err := file.Seek(offset.Num().Int64(), io.SeekStart) _, err := file.Seek(offset, io.SeekStart)
if err != nil { if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
} }
@@ -192,7 +192,7 @@ func ArRead(args ...any) (any, ArErr) {
if err != nil { if err != nil {
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true} return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
} }
return newNumber().SetInt64(info.Size()), ArErr{} return Number(info.Size()), ArErr{}
}}, }},
"ModTime": builtinFunc{"ModTime", func(...any) (any, ArErr) { "ModTime": builtinFunc{"ModTime", func(...any) (any, ArErr) {
info, err := file.Stat() info, err := file.Stat()

View File

@@ -5,14 +5,24 @@ import (
"math" "math"
) )
var N = newNumber().SetInt64(1e6) var N = Number(1e6)
func Ln(x number) number { func Ln(x ArObject) (any, ArErr) {
output := newNumber() var output any = Number(1)
output.SetInt64(1) var err ArErr
output.Quo(output, N) output, err = runOperation(
operationType{
operation: 15,
values: []any{x},
},
stack{},
0,
)
if err.EXISTS {
return nil, err
}
n1, _ := x.Float64() n1, _ := x_rational.Float64()
n2, _ := output.Float64() n2, _ := output.Float64()
output = newNumber().SetFloat64(math.Pow(n1, n2)) output = newNumber().SetFloat64(math.Pow(n1, n2))
output.Sub(output, newNumber().SetInt64(1)) output.Sub(output, newNumber().SetInt64(1))
@@ -34,10 +44,11 @@ func ArgonLn(a ...any) (any, ArErr) {
return nil, ArErr{TYPE: "Runtime Error", message: "ln takes a positive number", return nil, ArErr{TYPE: "Runtime Error", message: "ln takes a positive number",
EXISTS: true} EXISTS: true}
} }
return Ln(x), ArErr{} return Ln(x)
} }
var __ln10 = Ln(newNumber().SetInt64(10)) var __ln10, _ = Ln(Number(10))
func ArgonLog(a ...any) (any, ArErr) { func ArgonLog(a ...any) (any, ArErr) {
if len(a) != 1 { if len(a) != 1 {
@@ -53,7 +64,7 @@ func ArgonLog(a ...any) (any, ArErr) {
return nil, ArErr{TYPE: "Runtime Error", message: "log takes a positive number", return nil, ArErr{TYPE: "Runtime Error", message: "log takes a positive number",
EXISTS: true} EXISTS: true}
} }
return Ln(x).Quo(Ln(x), __ln10), ArErr{} return Ln(x).Quo(Ln(x), __ln10)
} }
func ArgonLogN(a ...any) (any, ArErr) { func ArgonLogN(a ...any) (any, ArErr) {

View File

@@ -13,12 +13,12 @@ var hexCompile = makeRegex("( *)(-)?(0x[a-fA-F0-9]+(\\.[a-fA-F0-9]+)?)( *)")
var octalCompile = makeRegex("( *)(-)?(0o[0-7]+(\\.[0-7]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)") var octalCompile = makeRegex("( *)(-)?(0o[0-7]+(\\.[0-7]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
// a number type // a number type
type number = *big.Rat // type number = *big.Rat
// create a new number type // create a new number type
func newNumber() *big.Rat { // func newNumber() *big.Rat {
return new(big.Rat) // return new(big.Rat)
} // }
func isNumber(code UNPARSEcode) bool { func isNumber(code UNPARSEcode) bool {
return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code) return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code)