7 Commits

46 changed files with 2720 additions and 961 deletions

View File

@@ -1,2 +1,2 @@
@echo off @echo off
go build -trimpath -ldflags="-s -w" -tags WINDOWS -o bin/argon.exe ./src go build -trimpath -ldflags="-s -w" -o bin/argon.exe ./src

View File

@@ -3,4 +3,4 @@
:: run the go run command passing the path to the main.go file, with the working directory set to the bin folder. pass in the arguments :: run the go run command passing the path to the main.go file, with the working directory set to the bin folder. pass in the arguments
set __ARGON_DEBUG__=true set __ARGON_DEBUG__=true
go run -tags WINDOWS ./src %* go run ./src %*

7
go.mod
View File

@@ -9,12 +9,7 @@ require (
require ( require (
github.com/chzyer/readline v1.5.1 // indirect github.com/chzyer/readline v1.5.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/joho/godotenv v1.5.1 // indirect github.com/joho/godotenv v1.5.1 // indirect
github.com/shirou/gopsutil v2.21.11+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
) )
require ( require (
@@ -26,7 +21,7 @@ require (
github.com/jwalton/go-supportscolor v1.1.0 github.com/jwalton/go-supportscolor v1.1.0
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
golang.org/x/sys v0.19.0 // indirect golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 golang.org/x/term v0.6.0
golang.org/x/text v0.8.0 golang.org/x/text v0.8.0
) )

13
go.sum
View File

@@ -6,8 +6,6 @@ github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jwalton/go-supportscolor v1.1.0 h1:HsXFJdMPjRUAx8cIW6g30hVSFYaxh9yRQwEWgkAR7lQ= github.com/jwalton/go-supportscolor v1.1.0 h1:HsXFJdMPjRUAx8cIW6g30hVSFYaxh9yRQwEWgkAR7lQ=
@@ -17,21 +15,12 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/shirou/gopsutil v2.21.11+incompatible h1:lOGOyCG67a5dv2hq5Z1BLDUqqKp3HkbjPcz5j6XMS0U=
github.com/shirou/gopsutil v2.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/wadey/go-rounding v1.1.0 h1:RAs9dMkB/uUHFv9ljlbRFC8/kBrQ5jhwt1GQq+2cciY= github.com/wadey/go-rounding v1.1.0 h1:RAs9dMkB/uUHFv9ljlbRFC8/kBrQ5jhwt1GQq+2cciY=
github.com/wadey/go-rounding v1.1.0/go.mod h1:/uD953tCL6Fea2Yp+LZBBp8d60QSObkMJxY6SPOJ5QE= github.com/wadey/go-rounding v1.1.0/go.mod h1:/uD953tCL6Fea2Yp+LZBBp8d60QSObkMJxY6SPOJ5QE=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -40,8 +29,6 @@ golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=

View File

@@ -17,12 +17,7 @@ ARGON 3 is a math-driven programming language designed to make code easy to read
- Cross-platform: Argon 3 can be run on any platform that has an interpreter for it. - Cross-platform: Argon 3 can be run on any platform that has an interpreter for it.
## 💻 Installation ## 💻 Installation
### Windows As of now, Argon 3 does not have an installer. Feel free to clone this repo and run the `build` file for your plateform. the build will be found in `bin/argon(.exe)`.
As of now, Argon 3 does not have a windows installer. Feel free to clone this repo and run the `build.bat` file. the build will be found in `bin\argon.exe`.
If you want to also use the isotope package manager, you can find the source code [here](https://github.com/open-argon/isotope).
### UNIX based (macOS and Linux)
Unix based operating systems can use the argon installer script found at [https://argon.wbell.dev/](https://argon.wbell.dev/). The script should run on all modern linux distros, and should also work on macOS with limited support. It may also work on other Unix based operating systems such at FreeBSD, but those are untested but are supported if you have issues.
## 📖 Usage ## 📖 Usage
To use Argon 3, you can create a file with the .ar extension and write your code in it. Then, you can run your code using the interpreter. For example, if you have a file called example.ar, you can run it using the following command: To use Argon 3, you can create a file with the .ar extension and write your code in it. Then, you can run your code using the interpreter. For example, if you have a file called example.ar, you can run it using the following command:

View File

@@ -4,6 +4,6 @@ let server = http.server()
let home(req,res) = do let home(req,res) = do
res.send("hello world") res.send("hello world")
server.get("/", home) server.get("/",home)
server.run() server.run()

View File

@@ -0,0 +1,4 @@
{
"name": "server-test",
"version": "1.0.0"
}

View File

@@ -0,0 +1 @@
[{"Name":"http.ar","Version":"1.1.6","URL":"https://isotope.wbell.dev/isotope-download?name=http.ar\u0026version=1.1.6","Remote":"isotope.wbell.dev"}]

View File

@@ -40,38 +40,28 @@ func parseAbs(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
} }
func runAbs(x ABS, stack stack, stacklevel int) (any, ArErr) { func runAbs(x ABS, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal(x.body, stack, stacklevel+1) value, err := runVal(x, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) != "number" { switch value := value.(type) {
return nil, ArErr{TYPE: "Runtime Error", case ArObject:
message: fmt.Sprintf("abs expected number, got %s", typeof(resp)), if Callable, ok := value.obj["__abs__"]; ok {
EXISTS: true, return runCall(call{
Callable: Callable,
Args: []any{},
Code: x.code,
Line: x.line,
Path: x.path,
}, stack, stacklevel)
} }
} }
return abs(resp.(number)), ArErr{} return nil, ArErr{
"TypeError",
fmt.Sprint("abs() not supported on ", typeof(value)),
x.line,
x.path,
x.code,
true,
}
} }
func abs(x number) number {
if x.Sign() < 0 {
return x.Neg(x)
}
return x
}
var ArAbs = builtinFunc{"abs", func(args ...any) (any, ArErr) {
if len(args) != 1 {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("abs expected 1 argument, got %d", len(args)),
EXISTS: true,
}
}
if typeof(args[0]) != "number" {
return nil, ArErr{TYPE: "Runtime Error",
message: fmt.Sprintf("abs expected number, got %s", typeof(args[0])),
EXISTS: true,
}
}
return abs(args[0].(number)), ArErr{}
}}

View File

@@ -25,6 +25,48 @@ func ArArray(arr []any) ArObject {
"__value__": arr, "__value__": arr,
}, },
} }
val.obj["__json__"] = builtinFunc{
"__json__",
func(args ...any) (any, ArErr) {
if len(args) != 1 {
return "", ArErr{
TYPE: "Type Error",
message: "expected 1 argument, got " + fmt.Sprint(len(args)),
EXISTS: true,
}
}
if typeof(args[0]) != "number" {
return "", ArErr{
TYPE: "Type Error",
message: "expected number, got " + typeof(args[0]),
EXISTS: true,
}
}
output := []string{}
level, err := numberToInt64(args[0].(ArObject))
if err != nil {
return "", ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
for _, value := range arr {
str, err := jsonstringify(value, level+1)
if err != nil {
return "", ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
output = append(output, str)
}
return "[" + strings.Join(output, ", ") + "]", ArErr{}
},
}
val.obj["__setindex__"] = builtinFunc{ val.obj["__setindex__"] = builtinFunc{
"__setindex__", "__setindex__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
@@ -38,18 +80,26 @@ 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,
} }
} }
if !a[0].(number).IsInt() { if !isNumberInt(a[0].(ArObject)) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "index must be an integer", message: "index must be an integer",
EXISTS: true, EXISTS: true,
} }
} }
num := int(a[0].(number).Num().Int64()) num64, err := numberToInt64(a[0].(ArObject))
if err != nil {
return nil, ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
num := int(num64)
if num < 0 || num >= len(arr) { if num < 0 || num >= len(arr) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Index Error", TYPE: "Index Error",
@@ -61,29 +111,6 @@ func ArArray(arr []any) ArObject {
return nil, ArErr{} return nil, ArErr{}
}, },
} }
val.obj["__Multiply__"] = builtinFunc{
"__Multiply__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "number" {
return nil, ArErr{"Type Error", "cannot multiply array by " + typeof(a[0]), 0, "", "", true}
}
n := a[0].(number)
if !n.IsInt() {
return nil, ArErr{"Value Error", "cannot multiply array by float", 0, "", "", true}
}
if n.Sign() < 0 {
return nil, ArErr{"Value Error", "cannot multiply array by negative number", 0, "", "", true}
}
size := int(n.Num().Int64())
retval := make([]any, 0, len(arr)*size)
for i := 0; i < size; i++ {
retval = append(retval, arr...)
}
return ArArray(retval), ArErr{}
}}
val.obj["__getindex__"] = builtinFunc{ val.obj["__getindex__"] = builtinFunc{
"__getindex__", "__getindex__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
@@ -98,7 +125,7 @@ func ArArray(arr []any) ArObject {
if typeof(a[0]) == "string" { if typeof(a[0]) == "string" {
var name = ArValidToAny(a[0]).(string) var name = ArValidToAny(a[0]).(string)
if name == "length" { if name == "length" {
return newNumber().SetInt64(int64(len(arr))), ArErr{} return Number(len(arr)), ArErr{}
} }
} }
} }
@@ -111,40 +138,64 @@ func ArArray(arr []any) ArObject {
{ {
if a[0] == nil { if a[0] == nil {
start = 0 start = 0
} else if typeof(a[0]) != "number" || !a[0].(number).IsInt() { } else if typeof(a[0]) != "number" || !isNumberInt(a[0].(ArObject)) {
return "", ArErr{ return "", ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "slice index must be an integer", message: "slice index must be an integer",
EXISTS: true, EXISTS: true,
} }
} else { } else {
start = int(a[0].(number).Num().Int64()) start64, err := numberToInt64(a[0].(ArObject))
if err != nil {
return "", ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
start = int(start64)
} }
} }
if len(a) > 1 { if len(a) > 1 {
if a[1] == nil { if a[1] == nil {
end = len(arr) end = len(arr)
} else if typeof(a[1]) != "number" || !a[1].(number).IsInt() { } else if typeof(a[1]) != "number" || !isNumberInt(a[1].(ArObject)) {
return "", ArErr{ return "", ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "slice index must be an integer", message: "slice index must be an integer",
EXISTS: true, EXISTS: true,
} }
} else { } else {
end = int(a[1].(number).Num().Int64()) end64, err := numberToInt64(a[1].(ArObject))
if err != nil {
return "", ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
end = int(end64)
} }
} }
if len(a) > 2 { if len(a) > 2 {
if a[2] == nil { if a[2] == nil {
step = 1 step = 1
} else if typeof(a[2]) != "number" || !a[2].(number).IsInt() { } else if typeof(a[2]) != "number" || !isNumberInt(a[2].(ArObject)) {
return "", ArErr{ return "", ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "slice index must be an integer", message: "slice index must be an integer",
EXISTS: true, EXISTS: true,
} }
} else { } else {
step = int(a[2].(number).Num().Int64()) step64, err := numberToInt64(a[2].(ArObject))
if err != nil {
return "", ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
step = int(step64)
} }
} }
var ogStart = start var ogStart = start
@@ -199,14 +250,22 @@ func ArArray(arr []any) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
if !args[0].(number).IsInt() { if !isNumberInt(args[0].(ArObject)) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "argument must be an integer", message: "argument must be an integer",
EXISTS: true, EXISTS: true,
} }
} }
num := int(args[0].(number).Num().Int64()) num64, err := (numberToInt64(args[0].(ArObject)))
if err != nil {
return nil, ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
num := int(num64)
if num < 0 || num >= len(arr) { if num < 0 || num >= len(arr) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Index Error", TYPE: "Index Error",
@@ -250,14 +309,22 @@ func ArArray(arr []any) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
if !args[0].(number).IsInt() { if !isNumberInt(args[0].(ArObject)) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "argument must be an integer", message: "argument must be an integer",
EXISTS: true, EXISTS: true,
} }
} }
num := int(args[0].(number).Num().Int64()) num64, err := numberToInt64(args[0].(ArObject))
if err != nil {
return nil, ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
num := int(num64)
if num < 0 || num > len(arr) { if num < 0 || num > len(arr) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Index Error", TYPE: "Index Error",
@@ -288,14 +355,22 @@ func ArArray(arr []any) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
if !args[0].(number).IsInt() { if !isNumberInt(args[0].(ArObject)) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "argument must be an integer", message: "argument must be an integer",
EXISTS: true, EXISTS: true,
} }
} }
num := int(args[0].(number).Num().Int64()) num64, err := (numberToInt64(args[0].(ArObject)))
if err != nil {
return nil, ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
num := int(num64)
if num < 0 || num >= len(arr) { if num < 0 || num >= len(arr) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Index Error", TYPE: "Index Error",
@@ -497,7 +572,7 @@ func ArArray(arr []any) ArObject {
} }
if len(arr) == 0 { if len(arr) == 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Value Error", TYPE: "ValueError",
message: "array is empty", message: "array is empty",
EXISTS: true, EXISTS: true,
} }

View File

@@ -1,5 +1,7 @@
package main package main
import "math/big"
func AnyToArValid(arr any) any { func AnyToArValid(arr any) any {
switch arr := arr.(type) { switch arr := arr.(type) {
case []any: case []any:
@@ -12,6 +14,8 @@ func AnyToArValid(arr any) any {
return ArBuffer(arr) return ArBuffer(arr)
case byte: case byte:
return ArByte(arr) return ArByte(arr)
case int, int64, float64, float32, *big.Rat, *big.Int:
return Number(arr)
default: default:
return arr return arr
} }
@@ -26,20 +30,3 @@ func ArValidToAny(a any) any {
} }
return a return a
} }
func ArValidToHash(a any) (any, ArErr) {
switch a := a.(type) {
case ArObject:
if callable, ok := a.obj["__hash__"]; ok {
value, err := runCall(call{
Callable: callable,
Args: []any{},
}, stack{}, 0)
if err.EXISTS {
return nil, err
}
return value, ArErr{}
}
}
return a, ArErr{}
}

View File

@@ -8,8 +8,6 @@ func anyToBool(x any) bool {
switch x := x.(type) { switch x := x.(type) {
case string: case string:
return x != "" return x != ""
case number:
return x.Cmp(newNumber()) != 0
case bool: case bool:
return x return x
case nil: case nil:

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"bytes" "bytes"
"encoding/hex"
"fmt" "fmt"
) )
@@ -15,19 +16,19 @@ func ArByte(Byte byte) ArObject {
obj.obj["__string__"] = builtinFunc{ obj.obj["__string__"] = builtinFunc{
"__string__", "__string__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
return "<byte>", ArErr{} return ArString("0x" + hex.EncodeToString([]byte{Byte})), ArErr{}
}, },
} }
obj.obj["__repr__"] = builtinFunc{ obj.obj["__repr__"] = builtinFunc{
"__repr__", "__repr__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
return "<byte>", ArErr{} return ArString("<byte 0x" + hex.EncodeToString([]byte{Byte}) + ">"), ArErr{}
}, },
} }
obj.obj["number"] = builtinFunc{ obj.obj["number"] = builtinFunc{
"number", "number",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
return newNumber().SetInt64(int64(Byte)), ArErr{} return Number(int64(Byte)), ArErr{}
}, },
} }
obj.obj["from"] = builtinFunc{ obj.obj["from"] = builtinFunc{
@@ -42,27 +43,19 @@ func ArByte(Byte byte) 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.Denom()) != 0 { if x > 255 || x < 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "ValueError",
message: "expected integer, got " + fmt.Sprint(x), message: "expected number between 0 and 255, got " + fmt.Sprint(x),
EXISTS: true, EXISTS: true,
} }
} }
n := x.Num().Int64() Byte = byte(x)
if n > 255 || n < 0 {
return nil, ArErr{
TYPE: "Value Error",
message: "expected number between 0 and 255, got " + fmt.Sprint(floor(x).Num().Int64()),
EXISTS: true,
}
}
Byte = byte(n)
case string: case string:
if len(x) != 1 { if len(x) != 1 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Value Error", TYPE: "ValueError",
message: "expected string of length 1, got " + fmt.Sprint(len(x)), message: "expected string of length 1, got " + fmt.Sprint(len(x)),
EXISTS: true, EXISTS: true,
} }
@@ -91,13 +84,13 @@ func ArBuffer(buf []byte) ArObject {
obj.obj["__string__"] = builtinFunc{ obj.obj["__string__"] = builtinFunc{
"__string__", "__string__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
return "<buffer>", ArErr{} return ArString("<buffer length=" + fmt.Sprint(len(buf)) + ">"), ArErr{}
}, },
} }
obj.obj["__repr__"] = builtinFunc{ obj.obj["__repr__"] = builtinFunc{
"__repr__", "__repr__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
return "<buffer>", ArErr{} return ArString("<buffer length=" + fmt.Sprint(len(buf)) + ">"), ArErr{}
}, },
} }
obj.obj["from"] = builtinFunc{ obj.obj["from"] = builtinFunc{
@@ -119,16 +112,17 @@ func ArBuffer(buf []byte) ArObject {
case []any: case []any:
outputbuf := []byte{} outputbuf := []byte{}
for _, v := range x { for _, v := range x {
switch y := v.(type) { V := ArValidToAny(v)
case number: switch y := V.(type) {
if y.Denom().Cmp(one.Denom()) != 0 { case int64:
if y > 255 || y < 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "ValueError",
message: "Cannot convert non-integer to byte", message: "expected number between 0 and 255, got " + fmt.Sprint(y),
EXISTS: true, EXISTS: true,
} }
} }
outputbuf = append(outputbuf, byte(y.Num().Int64())) outputbuf = append(outputbuf, byte(y))
default: default:
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
@@ -176,15 +170,14 @@ func ArBuffer(buf []byte) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
nNum := nVal.(number) n, err := numberToInt64(nVal.(ArObject))
if nNum.Denom().Cmp(one.Denom()) != 0 { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "expected integer, got " + fmt.Sprint(nNum), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
n := nNum.Num().Int64()
var result [][]byte var result [][]byte
start := 0 start := 0
var i int64 var i int64
@@ -258,39 +251,37 @@ func ArBuffer(buf []byte) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
startVal := ArValidToAny(a[0]) if typeof(a[0]) != "number" || typeof(a[1]) != "number" {
if typeof(startVal) != "number" {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "expected number, got " + typeof(startVal), message: "expected number, got " + typeof(a[0]) + " and " + typeof(a[1]),
EXISTS: true, EXISTS: true,
} }
} }
start := startVal.(number) start, err := numberToInt64(ArValidToAny(a[0]).(ArObject))
if start.Denom().Cmp(one.Denom()) != 0 { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "expected integer, got " + fmt.Sprint(start), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
endVal := ArValidToAny(a[1]) end, err := numberToInt64(ArValidToAny(a[1]).(ArObject))
if typeof(endVal) != "number" { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "expected number, got " + typeof(endVal), message: err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
end := endVal.(number) if start < 0 || end < 0 || start > int64(len(buf)) || end > int64(len(buf)) {
if end.Denom().Cmp(one.Denom()) != 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Index Error",
message: "expected integer, got " + fmt.Sprint(end), message: "index out of range",
EXISTS: true, EXISTS: true,
} }
} }
return ArBuffer(buf[floor(start).Num().Int64():floor(end).Num().Int64()]), ArErr{} return ArBuffer(buf[start:end]), ArErr{}
}, },
} }
obj.obj["to"] = builtinFunc{ obj.obj["to"] = builtinFunc{
@@ -323,7 +314,7 @@ func ArBuffer(buf []byte) ArObject {
case "array": case "array":
output := []any{} output := []any{}
for _, v := range buf { for _, v := range buf {
output = append(output, newNumber().SetInt64(int64(v))) output = append(output, Number(int64(v)))
} }
return ArArray(output), ArErr{} return ArArray(output), ArErr{}
default: default:
@@ -347,15 +338,15 @@ func ArBuffer(buf []byte) 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.Denom()) != 0 { if x > 255 || x < 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "ValueError",
message: "Cannot convert non-integer to byte", message: "expected number between 0 and 255, got " + fmt.Sprint(x),
EXISTS: true, EXISTS: true,
} }
} }
buf = append(buf, byte(x.Num().Int64())) buf = append(buf, byte(x))
case string: case string:
buf = append(buf, []byte(x)...) buf = append(buf, []byte(x)...)
case []byte: case []byte:
@@ -363,15 +354,15 @@ func ArBuffer(buf []byte) ArObject {
case []any: case []any:
for _, v := range x { for _, v := range x {
switch y := v.(type) { switch y := v.(type) {
case number: case int64:
if y.Denom().Cmp(one.Denom()) != 0 { if y > 255 || y < 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "ValueError",
message: "Cannot convert non-integer to byte", message: "expected number between 0 and 255, got " + fmt.Sprint(y),
EXISTS: true, EXISTS: true,
} }
} }
buf = append(buf, byte(y.Num().Int64())) buf = append(buf, byte(y))
default: default:
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
@@ -410,25 +401,24 @@ func ArBuffer(buf []byte) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
pos := poss.(number) posNum, err := numberToInt64(poss.(ArObject))
if pos.Denom().Cmp(one.Denom()) != 0 { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "position must be an integer", message: err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
posNum := pos.Num().Int64()
switch x := values.(type) { switch x := values.(type) {
case number: case int64:
if x.Denom().Cmp(one.Denom()) != 0 { if x > 255 || x < 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "ValueError",
message: "Cannot convert non-integer to byte", message: "expected number between 0 and 255, got " + fmt.Sprint(x),
EXISTS: true, EXISTS: true,
} }
} }
buf = append(buf[:posNum], append([]byte{byte(x.Num().Int64())}, buf[posNum:]...)...) buf = append(buf[:posNum], append([]byte{byte(x)}, buf[posNum:]...)...)
case string: case string:
buf = append(buf[:posNum], append([]byte(x), buf[posNum:]...)...) buf = append(buf[:posNum], append([]byte(x), buf[posNum:]...)...)
case []byte: case []byte:
@@ -436,15 +426,15 @@ func ArBuffer(buf []byte) ArObject {
case []any: case []any:
for _, v := range x { for _, v := range x {
switch y := v.(type) { switch y := v.(type) {
case number: case int64:
if y.Denom().Cmp(one.Denom()) != 0 { if y > 255 || y < 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "ValueError",
message: "Cannot convert non-integer to byte", message: "expected number between 0 and 255, got " + fmt.Sprint(y),
EXISTS: true, EXISTS: true,
} }
} }
buf = append(buf[:posNum], append([]byte{byte(y.Num().Int64())}, buf[posNum:]...)...) buf = append(buf[:posNum], append([]byte{byte(y)}, buf[posNum:]...)...)
default: default:
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
@@ -479,12 +469,12 @@ func ArBuffer(buf []byte) ArObject {
if typeof(a[0]) == "string" { if typeof(a[0]) == "string" {
var name = ArValidToAny(a[0]).(string) var name = ArValidToAny(a[0]).(string)
if name == "length" { if name == "length" {
return newNumber().SetInt64(int64(len(buf))), ArErr{} return Number(len(buf)), ArErr{}
} }
} }
} }
} }
poss := ArValidToAny(a[0]) poss := a[0]
if typeof(poss) != "number" { if typeof(poss) != "number" {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
@@ -492,15 +482,14 @@ func ArBuffer(buf []byte) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
pos := poss.(number) posNum, err := numberToInt64(poss.(ArObject))
if pos.Denom().Cmp(one.Denom()) != 0 { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "position must be an integer", message: err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
posNum := pos.Num().Int64()
if posNum < 0 || posNum >= int64(len(buf)) { if posNum < 0 || posNum >= int64(len(buf)) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Index Error", TYPE: "Index Error",
@@ -529,15 +518,21 @@ func ArBuffer(buf []byte) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
pos := poss.(number) posNum, err := numberToInt64(poss.(ArObject))
if pos.Denom().Cmp(one.Denom()) != 0 { if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
message: "position must be an integer", message: err.Error(),
EXISTS: true,
}
}
if posNum < 0 || posNum >= int64(len(buf)) {
return nil, ArErr{
TYPE: "Index Error",
message: "index out of range",
EXISTS: true, EXISTS: true,
} }
} }
posNum := pos.Num().Int64()
buf = append(buf[:posNum], buf[posNum+1:]...) buf = append(buf[:posNum], buf[posNum+1:]...)
obj.obj["__value__"] = buf obj.obj["__value__"] = buf
return obj, ArErr{} return obj, ArErr{}

View File

@@ -19,7 +19,7 @@ func ArgonString(args ...any) (any, ArErr) {
func ArgonNumber(args ...any) (any, ArErr) { func ArgonNumber(args ...any) (any, ArErr) {
if len(args) == 0 { if len(args) == 0 {
return newNumber(), ArErr{} return _zero_Number, ArErr{}
} }
args[0] = ArValidToAny(args[0]) args[0] = ArValidToAny(args[0])
switch x := args[0].(type) { switch x := args[0].(type) {
@@ -27,17 +27,17 @@ func ArgonNumber(args ...any) (any, ArErr) {
if !isNumber(UNPARSEcode{code: x}) { if !isNumber(UNPARSEcode{code: x}) {
return nil, ArErr{TYPE: "Conversion Error", message: "Cannot convert " + anyToArgon(x, true, true, 3, 0, false, 0) + " to a number", EXISTS: true} return nil, ArErr{TYPE: "Conversion Error", message: "Cannot convert " + anyToArgon(x, true, true, 3, 0, false, 0) + " to a number", EXISTS: true}
} }
N, _ := newNumber().SetString(x) N := Number(x)
return N, ArErr{} return N, ArErr{}
case number: case int64, *big.Int, *big.Rat:
return x, ArErr{} return Number(x), ArErr{}
case bool: case bool:
if x { if x {
return newNumber().SetInt64(1), ArErr{} return _one_Number, ArErr{}
} }
return newNumber(), ArErr{} return _zero_Number, ArErr{}
case nil: case nil:
return newNumber(), ArErr{} return _zero_Number, ArErr{}
} }
return nil, ArErr{TYPE: "Number Error", message: "Cannot convert " + typeof(args[0]) + " to a number", EXISTS: true} return nil, ArErr{TYPE: "Number Error", message: "Cannot convert " + typeof(args[0]) + " to a number", EXISTS: true}
@@ -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

@@ -9,17 +9,15 @@ func makeGlobal() ArObject {
var vars = anymap{} var vars = anymap{}
vars["global"] = vars vars["global"] = vars
vars["env"] = env vars["env"] = env
vars["platform"] = platform
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{
"server": builtinFunc{"server", ArSocketServer}, "server": builtinFunc{"server", ArSocketServer},
"client": builtinFunc{"client", ArSocketClient}, "client": builtinFunc{"client", ArSocketClient},
}) })
vars["infinity"] = infinity
vars["eval"] = builtinFunc{"eval", AReval} vars["eval"] = builtinFunc{"eval", AReval}
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) { vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
@@ -67,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.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}
}} }}
@@ -133,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}
}} }}
@@ -158,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}
}} }}
@@ -168,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}
}} }}
@@ -194,15 +190,12 @@ func makeGlobal() ArObject {
vars["todeg"] = ArToDeg vars["todeg"] = ArToDeg
vars["colour"] = ArColour vars["colour"] = ArColour
vars["torad"] = ArToRad vars["torad"] = ArToRad
vars["abs"] = ArAbs
vars["fraction"] = builtinFunc{"fraction", func(a ...any) (any, ArErr) { vars["fraction"] = builtinFunc{"fraction", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
return nil, ArErr{TYPE: "fraction", message: "fraction takes 1 argument", return nil, ArErr{TYPE: "fraction", message: "fraction takes 1 argument",
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(
@@ -230,7 +223,7 @@ func makeGlobal() ArObject {
case ArObject: case ArObject:
newarray := []any{} newarray := []any{}
for key := range x.obj { for key := range x.obj {
newarray = append(newarray, key) newarray = append(newarray, AnyToArValid(key))
} }
return ArArray(newarray), ArErr{} return ArArray(newarray), ArErr{}
} }
@@ -242,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{}
@@ -253,9 +248,10 @@ func makeGlobal() ArObject {
if len(a) != 1 { if len(a) != 1 {
return nil, ArErr{TYPE: "chr", message: "chr takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true} return nil, ArErr{TYPE: "chr", message: "chr takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
} }
a[0] = ArValidToAny(a[0])
switch x := a[0].(type) { switch x := a[0].(type) {
case number: case int64:
return string([]rune{rune(floor(x).Num().Int64())}), ArErr{} return string([]rune{rune(x)}), 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}
}} }}
@@ -267,9 +263,9 @@ func makeGlobal() ArObject {
switch x := a[0].(type) { switch x := a[0].(type) {
case string: case string:
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(x)), 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}
}} }}
@@ -283,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
} }
} }
} }
@@ -310,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

@@ -19,8 +19,16 @@ var ArColour = Map(
} }
var c *color.Color var c *color.Color
var s string var s string
if x, ok := a[0].(number); ok { if x, ok := a[0].(ArObject); ok {
c = color.Set(color.Attribute(x.Num().Int64())) colour_int64, err := numberToInt64(x)
if err != nil {
return nil, ArErr{
TYPE: "Type Error",
message: err.Error(),
EXISTS: true,
}
}
c = color.New(color.Attribute(colour_int64))
} else { } else {
return nil, ArErr{ return nil, ArErr{
TYPE: "Type Error", TYPE: "Type Error",
@@ -45,52 +53,52 @@ var ArColour = Map(
}}, }},
"bg": Map( "bg": Map(
anymap{ anymap{
"black": newNumber().SetInt64(int64(color.BgBlack)), "black": Number(int64(color.BgBlack)),
"red": newNumber().SetInt64(int64(color.BgRed)), "red": Number(int64(color.BgRed)),
"green": newNumber().SetInt64(int64(color.BgGreen)), "green": Number(int64(color.BgGreen)),
"yellow": newNumber().SetInt64(int64(color.BgYellow)), "yellow": Number(int64(color.BgYellow)),
"blue": newNumber().SetInt64(int64(color.BgBlue)), "blue": Number(int64(color.BgBlue)),
"magenta": newNumber().SetInt64(int64(color.BgMagenta)), "magenta": Number(int64(color.BgMagenta)),
"cyan": newNumber().SetInt64(int64(color.BgCyan)), "cyan": Number(int64(color.BgCyan)),
"white": newNumber().SetInt64(int64(color.BgWhite)), "white": Number(int64(color.BgWhite)),
"hiBlack": newNumber().SetInt64(int64(color.BgHiBlack)), "hiBlack": Number(int64(color.BgHiBlack)),
"hiRed": newNumber().SetInt64(int64(color.BgHiRed)), "hiRed": Number(int64(color.BgHiRed)),
"hiGreen": newNumber().SetInt64(int64(color.BgHiGreen)), "hiGreen": Number(int64(color.BgHiGreen)),
"hiYellow": newNumber().SetInt64(int64(color.BgHiYellow)), "hiYellow": Number(int64(color.BgHiYellow)),
"hiBlue": newNumber().SetInt64(int64(color.BgHiBlue)), "hiBlue": Number(int64(color.BgHiBlue)),
"hiMagenta": newNumber().SetInt64(int64(color.BgHiMagenta)), "hiMagenta": Number(int64(color.BgHiMagenta)),
"hiCyan": newNumber().SetInt64(int64(color.BgHiCyan)), "hiCyan": Number(int64(color.BgHiCyan)),
"hiWhite": newNumber().SetInt64(int64(color.BgHiWhite)), "hiWhite": Number(int64(color.BgHiWhite)),
}, },
), ),
"fg": Map( "fg": Map(
anymap{ anymap{
"black": newNumber().SetInt64(int64(color.FgBlack)), "black": Number(int64(color.FgBlack)),
"red": newNumber().SetInt64(int64(color.FgRed)), "red": Number(int64(color.FgRed)),
"green": newNumber().SetInt64(int64(color.FgGreen)), "green": Number(int64(color.FgGreen)),
"yellow": newNumber().SetInt64(int64(color.FgYellow)), "yellow": Number(int64(color.FgYellow)),
"blue": newNumber().SetInt64(int64(color.FgBlue)), "blue": Number(int64(color.FgBlue)),
"magenta": newNumber().SetInt64(int64(color.FgMagenta)), "magenta": Number(int64(color.FgMagenta)),
"cyan": newNumber().SetInt64(int64(color.FgCyan)), "cyan": Number(int64(color.FgCyan)),
"white": newNumber().SetInt64(int64(color.FgWhite)), "white": Number(int64(color.FgWhite)),
"hiBlack": newNumber().SetInt64(int64(color.FgHiBlack)), "hiBlack": Number(int64(color.FgHiBlack)),
"hiRed": newNumber().SetInt64(int64(color.FgHiRed)), "hiRed": Number(int64(color.FgHiRed)),
"hiGreen": newNumber().SetInt64(int64(color.FgHiGreen)), "hiGreen": Number(int64(color.FgHiGreen)),
"hiYellow": newNumber().SetInt64(int64(color.FgHiYellow)), "hiYellow": Number(int64(color.FgHiYellow)),
"hiBlue": newNumber().SetInt64(int64(color.FgHiBlue)), "hiBlue": Number(int64(color.FgHiBlue)),
"hiMagenta": newNumber().SetInt64(int64(color.FgHiMagenta)), "hiMagenta": Number(int64(color.FgHiMagenta)),
"hiCyan": newNumber().SetInt64(int64(color.FgHiCyan)), "hiCyan": Number(int64(color.FgHiCyan)),
"hiWhite": newNumber().SetInt64(int64(color.FgHiWhite)), "hiWhite": Number(int64(color.FgHiWhite)),
}, },
), ),
"reset": newNumber().SetInt64(int64(color.Reset)), "reset": Number(int64(color.Reset)),
"bold": newNumber().SetInt64(int64(color.Bold)), "bold": Number(int64(color.Bold)),
"faint": newNumber().SetInt64(int64(color.Faint)), "faint": Number(int64(color.Faint)),
"italic": newNumber().SetInt64(int64(color.Italic)), "italic": Number(int64(color.Italic)),
"underline": newNumber().SetInt64(int64(color.Underline)), "underline": Number(int64(color.Underline)),
"blinkSlow": newNumber().SetInt64(int64(color.BlinkSlow)), "blinkSlow": Number(int64(color.BlinkSlow)),
"blinkRapid": newNumber().SetInt64(int64(color.BlinkRapid)), "blinkRapid": Number(int64(color.BlinkRapid)),
"reverseVideo": newNumber().SetInt64(int64(color.ReverseVideo)), "reverseVideo": Number(int64(color.ReverseVideo)),
"concealed": newNumber().SetInt64(int64(color.Concealed)), "concealed": Number(int64(color.Concealed)),
"crossedOut": newNumber().SetInt64(int64(color.CrossedOut)), "crossedOut": Number(int64(color.CrossedOut)),
}) })

View File

@@ -35,7 +35,8 @@ func debugInit() {
} }
func debugPrintln(a ...any) { func debugPrintln(a ...any) {
if debug { switch debug {
case true:
__debugPrintsLock.Lock() __debugPrintsLock.Lock()
__debugPrints = append(__debugPrints, a) __debugPrints = append(__debugPrints, a)
__debugPrintsLock.Unlock() __debugPrintsLock.Unlock()

View File

@@ -28,36 +28,26 @@ func isFactorial(code UNPARSEcode) bool {
return factorialCompiled.MatchString(code.code) return factorialCompiled.MatchString(code.code)
} }
func fact(n number) number {
if n.Cmp(newNumber().SetInt64(1000)) >= 0 {
return infinity
} else if n.Cmp(newNumber().SetInt64(0)) == -1 {
return newNumber().SetInt64(0)
} else if n.Cmp(newNumber().SetInt64(0)) == 0 {
return newNumber().SetInt64(1)
}
result := newNumber().SetInt64(1)
for i := newNumber().SetInt64(2); i.Cmp(n) <= 0; i.Add(i, newNumber().SetInt64(1)) {
result.Mul(result, i)
}
return result
}
func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) { func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) {
val, err := runVal(f.value, stack, stacklevel+1) val, err := runVal(f.value, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
switch x := val.(type) { switch val := val.(type) {
case number: case ArObject:
if !x.IsInt() { if callable, ok := val.obj["__factorial__"]; ok {
return nil, ArErr{"Runtime Error", "cannot use factorial on non-integer", f.line, f.path, f.code, true} return runCall(call{
Callable: callable,
Args: []any{},
Code: f.code,
Line: f.line,
Path: f.path,
}, stack, stacklevel)
} }
if x.Cmp(newNumber().SetInt64(0)) == -1 { }
return nil, ArErr{"Runtime Error", "cannot use factorial on negative number", f.line, f.path, f.code, true} return nil, ArErr{
} TYPE: "TypeError",
return fact(x), ArErr{} message: "factorial not defined for type",
default: EXISTS: true,
return nil, ArErr{"Runtime Error", "cannot use factorial on non-number of type '" + typeof(val) + "'", f.line, f.path, f.code, true}
} }
} }

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

@@ -51,7 +51,7 @@ func parseForLoop(code UNPARSEcode, index int, codelines []UNPARSEcode) (forLoop
innertotalstep += stepstep - 1 innertotalstep += stepstep - 1
stepval = stepval_ stepval = stepval_
} else { } else {
stepval = newNumber().SetInt64(1) stepval = _one_Number
} }
to := strings.TrimSpace(valsplit[0]) to := strings.TrimSpace(valsplit[0])
toval, worked, err, tostep := translateVal(UNPARSEcode{code: to, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0) toval, worked, err, tostep := translateVal(UNPARSEcode{code: to, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0)
@@ -83,7 +83,7 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
if typeof(fromval) != "number" { if typeof(fromval) != "number" {
return nil, ArErr{"Type Error", "for loop from value must be a number", loop.line, loop.path, loop.code, true} return nil, ArErr{"Type Error", "for loop from value must be a number", loop.line, loop.path, loop.code, true}
} }
from := fromval.(number) from := fromval.(ArObject)
toval, err := runVal(loop.to, stack, stacklevel+1) toval, err := runVal(loop.to, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
@@ -91,7 +91,7 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
if typeof(toval) != "number" { if typeof(toval) != "number" {
return nil, ArErr{"Type Error", "for loop to value must be a number", loop.line, loop.path, loop.code, true} return nil, ArErr{"Type Error", "for loop to value must be a number", loop.line, loop.path, loop.code, true}
} }
to := toval.(number) to := toval.(ArObject)
stepval, err := runVal(loop.step, stack, stacklevel+1) stepval, err := runVal(loop.step, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
@@ -99,11 +99,52 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
if typeof(stepval) != "number" { if typeof(stepval) != "number" {
return nil, ArErr{"Type Error", "for loop step value must be a number", loop.line, loop.path, loop.code, true} return nil, ArErr{"Type Error", "for loop step value must be a number", loop.line, loop.path, loop.code, true}
} }
step := stepval.(number) step := stepval.(ArObject)
for i := newNumber().Set(from); i.Cmp(to) == -1; i = i.Add(i, step) { if isNumberInt64(from) && isNumberInt64(to) && isNumberInt64(step) {
resp, err := runVal(loop.body, append(stack, Map(anymap{ i, _ := numberToInt64(from)
loop.variable: newNumber().Set(i), to_, _ := numberToInt64(to)
})), stacklevel+1) step_, _ := numberToInt64(step)
layer := anymap{}
stacks := append(stack, Map(layer))
for i < to_ {
layer[loop.variable] = Number(i)
resp, err := runVal(loop.body, stacks, stacklevel+1)
if err.EXISTS {
return nil, err
}
switch x := resp.(type) {
case Return:
return x, ArErr{}
case Break:
return nil, ArErr{}
case Continue:
}
i += step_
}
return nil, ArErr{}
}
i := from
direction_obj, err := CompareObjects(step, _zero_Number)
if err.EXISTS {
return nil, err
}
currentDirection_obj, err := CompareObjects(to, i)
if err.EXISTS {
return nil, err
}
currentDirection, error := numberToInt64(currentDirection_obj)
if error != nil {
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
}
direction, error := numberToInt64(direction_obj)
if error != nil {
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
}
layer := anymap{}
stacks := append(stack, Map(layer))
for currentDirection == direction {
layer[loop.variable] = i
resp, err := runVal(loop.body, stacks, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -113,7 +154,22 @@ func runForLoop(loop forLoop, stack stack, stacklevel int) (any, ArErr) {
case Break: case Break:
return nil, ArErr{} return nil, ArErr{}
case Continue: case Continue:
continue }
i, err = AddObjects(i, step)
if err.EXISTS {
return nil, err
}
currentDirection_obj, err = CompareObjects(to, i)
if err.EXISTS {
return nil, err
}
currentDirection, error = numberToInt64(currentDirection_obj)
if error != nil {
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
}
direction, error = numberToInt64(direction_obj)
if error != nil {
return nil, ArErr{"Type Error", error.Error(), loop.line, loop.path, loop.code, true}
} }
} }
return nil, ArErr{} return nil, ArErr{}

View File

@@ -123,19 +123,10 @@ func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapG
}, 1 }, 1
} }
var hashabletypes = []string{
"number",
"string",
"bool",
"null",
}
func isUnhashable(val any) bool { func isUnhashable(val any) bool {
keytype := typeof(val) switch val.(type) {
for _, v := range hashabletypes { case int64, float64, string, bool, nil:
if v == keytype { return false
return false
}
} }
return true return true
} }

View File

@@ -156,7 +156,6 @@ func translateImport(realpath string, origin string, topLevelOnly bool) (transla
importing[p] = true importing[p] = true
translated, translationerr := translate(codelines) translated, translationerr := translate(codelines)
debugPrintln(translated...)
importing[p] = false importing[p] = false
if translationerr.EXISTS { if translationerr.EXISTS {

View File

@@ -2,13 +2,59 @@ package main
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"github.com/chzyer/readline"
"golang.org/x/term" "golang.org/x/term"
) )
var tempFilePath = os.TempDir() + "/argon_input_history.tmp" var tempFilePath = os.TempDir() + "/argon_input_history.tmp"
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
HistoryFile: tempFilePath,
HistorySearchFold: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
MaskRune: '*',
EnableMask: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}
func pause() { func pause() {
fmt.Print("Press Enter to continue...") fmt.Print("Press Enter to continue...")
term.ReadPassword(int(os.Stdin.Fd())) term.ReadPassword(int(os.Stdin.Fd()))

View File

@@ -1,55 +0,0 @@
//go:build !WINDOWS
// +build !WINDOWS
package main
import (
"fmt"
"log"
"github.com/chzyer/readline"
)
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
HistoryFile: tempFilePath,
HistorySearchFold: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
message := fmt.Sprint(output...)
rl, err := readline.NewEx(&readline.Config{
Prompt: message,
MaskRune: '*',
EnableMask: true,
})
if err != nil {
log.Fatalf("Failed to create readline instance: %v", err)
}
defer rl.Close()
line, err := rl.Readline()
if err != nil { // io.EOF or other error
return "", err
}
return line, nil
}

View File

@@ -1,63 +0,0 @@
//go:build WINDOWS
// +build WINDOWS
package main
import (
"bufio"
"fmt"
"os"
"golang.org/x/term"
)
func input(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
input := scanner.Text()
return input, nil
}
func getPassword(args ...any) (string, error) {
output := []any{}
for i := 0; i < len(args); i++ {
output = append(output, anyToArgon(args[i], false, true, 3, 0, true, 0))
}
fmt.Print(output...)
password := []byte{}
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer term.Restore(int(os.Stdin.Fd()), oldState)
for {
char := make([]byte, 1)
_, err := os.Stdin.Read(char)
if err != nil {
return "", err
}
if char[0] == 3 || char[0] == 4 {
return "", fmt.Errorf("keyboard interupt")
} else if char[0] == '\r' || char[0] == '\n' {
fmt.Println()
break
} else if char[0] == '\b' || char[0] == 127 {
if len(password) > 0 {
password = password[:len(password)-1]
fmt.Print("\b \b")
}
} else {
password = append(password, char[0])
fmt.Print("*")
}
}
fmt.Print("\r")
return string(password), nil
}

View File

@@ -3,9 +3,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"math"
"strconv" "strconv"
"strings"
) )
func convertToArgon(obj any) any { func convertToArgon(obj any) any {
@@ -24,7 +22,7 @@ func convertToArgon(obj any) any {
case string: case string:
return ArString(x) return ArString(x)
case float64: case float64:
return newNumber().SetFloat64(x) return Number(x)
case bool: case bool:
return x return x
case nil: case nil:
@@ -36,43 +34,37 @@ func convertToArgon(obj any) any {
func jsonparse(str string) (any, ArErr) { func jsonparse(str string) (any, ArErr) {
var jsonMap any var jsonMap any
var err = json.Unmarshal([]byte(str), &jsonMap) var err = json.Unmarshal([]byte(str), &jsonMap)
if err != nil {return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}} if err != nil {
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
return convertToArgon(jsonMap), ArErr{} return convertToArgon(jsonMap), ArErr{}
} }
func jsonstringify(obj any, level int) (string, error) { func jsonstringify(obj any, level int64) (string, error) {
if level > 100 { if level > 100 {
return "", errors.New("json stringify error: too many levels") return "", errors.New("json stringify error: too many levels")
} }
output := []string{}
obj = ArValidToAny(obj)
switch x := obj.(type) { switch x := obj.(type) {
case anymap: case ArObject:
for key, value := range x { if callable, ok := x.obj["__json__"]; ok {
str, err := jsonstringify(value, level+1) val, err := runCall(
if err != nil { call{
return "", err Callable: callable,
Args: []any{Int64ToNumber(level)},
},
stack{},
0,
)
if err.EXISTS {
return "", errors.New(err.message)
} }
output = append(output, ""+strconv.Quote(anyToArgon(key, false, true, 3, 0, false, 0))+": "+str) val = ArValidToAny(val)
} if x, ok := val.(string); ok {
return "{" + strings.Join(output, ", ") + "}", nil return x, nil
case []any: } else {
for _, value := range x { return "", errors.New("json stringify error: __json__ must return a string")
str, err := jsonstringify(value, level+1)
if err != nil {
return "", err
} }
output = append(output, str)
} }
return "[" + strings.Join(output, ", ") + "]", nil
case string:
return strconv.Quote(x), nil
case number:
num, _ := x.Float64()
if math.IsNaN(num) || math.IsInf(num, 0) {
return "null", nil
}
return numberToString(x, false), nil
case bool: case bool:
return strconv.FormatBool(x), nil return strconv.FormatBool(x), nil
case nil: case nil:
@@ -94,10 +86,21 @@ var ArJSON = Map(anymap{
return jsonparse(args[0].(string)) return jsonparse(args[0].(string))
}}, }},
"stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) { "stringify": builtinFunc{"stringify", func(args ...any) (any, ArErr) {
if len(args) == 0 { if len(args) != 1 && len(args) != 2 {
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 argument", EXISTS: true} return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 or 2 arguments", EXISTS: true}
} }
str, err := jsonstringify(args[0], 0) var level int64 = 0
if len(args) == 2 {
if typeof(args[1]) != "number" {
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes a number not a '" + typeof(args[1]) + "'", EXISTS: true}
}
var err error
level, err = numberToInt64(args[1].(ArObject))
if err != nil {
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
}
}
str, err := jsonstringify(args[0], level)
if err != nil { if err != nil {
return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true} return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
} }

View File

@@ -5,19 +5,26 @@ 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))
if output == nil {
output = infinity
}
output.Sub(output, newNumber().SetInt64(1)) output.Sub(output, newNumber().SetInt64(1))
output.Mul(output, N) output.Mul(output, N)
return output return output
@@ -37,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 {
@@ -56,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

@@ -10,8 +10,8 @@ var Args = os.Args[1:]
type stack = []ArObject type stack = []ArObject
const VERSION = "3.0.11" const VERSION = "3.1.0 oop numbers beta 1"
const VERSION_NUM = 9 const VERSION_NUM = 7
func newscope() ArObject { func newscope() ArObject {
return Map(anymap{}) return Map(anymap{})
@@ -23,7 +23,7 @@ func main() {
if !debug { if !debug {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
fmt.Println("There was a fundamental error in argon v3 that caused it to crash.") fmt.Println("There was a fundamental error in argon v" + VERSION + " that caused it to crash.")
fmt.Println() fmt.Println()
fmt.Println("website:", website) fmt.Println("website:", website)
fmt.Println("docs:", docs) fmt.Println("docs:", docs)
@@ -45,7 +45,6 @@ func main() {
} }
}() }()
} }
initRandom()
garbageCollect() garbageCollect()
global := makeGlobal() global := makeGlobal()
if len(Args) == 0 { if len(Args) == 0 {

View File

@@ -245,6 +245,7 @@ func Map(m anymap) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
args[0] = ArValidToAny(args[0])
if isUnhashable(args[0]) { if isUnhashable(args[0]) {
return nil, ArErr{ return nil, ArErr{
TYPE: "Runtime Error", TYPE: "Runtime Error",

View File

@@ -1,5 +1,13 @@
package main package main
var PI, _ = newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989") import "math/big"
var e, _ = newNumber().SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
var infinity, _ = newNumber().SetString("1e1000") var PI_RAT, _ = new(big.Rat).SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
var PI ArObject
var e_RAT, _ = new(big.Rat).SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
var e ArObject
func init() {
PI = Number(PI_RAT)
e = Number(e_RAT)
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"math"
"reflect" "reflect"
"strings" "strings"
) )
@@ -20,15 +19,13 @@ var operations = []string{
"==", "==",
"+", "+",
"-", "-",
"%",
"*", "*",
"%",
"//", "//",
"/", "/",
"^", "^",
} }
var one = newNumber().SetInt64(1)
type operationType struct { type operationType struct {
operation int operation int
values []any values []any
@@ -74,7 +71,7 @@ func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (oper
path: code.path, path: code.path,
}, index, codelines, 0) }, index, codelines, 0)
if !success || err.EXISTS { if !success || err.EXISTS {
return operationType{}, success, err, 0 continue
} }
values = append(values, resp) values = append(values, resp)
totalStep += respindex - 1 totalStep += respindex - 1
@@ -120,9 +117,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
} }
switch o.operation { switch o.operation {
case 4: case 4:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) <= 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__LessThanEqual__"]; ok { if y, ok := x.obj["__LessThanEqual__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -147,9 +142,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 5: case 5:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) >= 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__GreaterThanEqual__"]; ok { if y, ok := x.obj["__GreaterThanEqual__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -174,9 +167,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 6: case 6:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) < 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__LessThan__"]; ok { if y, ok := x.obj["__LessThan__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -201,9 +192,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 7: case 7:
if isAnyNumber(resp) && isAnyNumber(resp2) { if x, ok := resp.(ArObject); ok {
return resp.(number).Cmp(resp2.(number)) > 0, ArErr{}
} else if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__GreaterThan__"]; ok { if y, ok := x.obj["__GreaterThan__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -253,9 +242,6 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -265,10 +251,7 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
output = output.(number).Sub(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Subtract__"]; ok { if y, ok := x.obj["__Subtract__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -309,33 +292,17 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" && typeof(output) == "number" { if x, ok := output.(ArObject); ok {
if resp.(number).Cmp(newNumber().SetInt64(0)) == 0 {
return nil, ArErr{
"Runtime Error",
"Cannot divide by zero",
o.line,
o.path,
o.code,
true,
}
}
output = output.(number).Quo(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Divide__"]; ok { if y, ok := x.obj["__Divide__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -375,9 +342,6 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
var output any = resp var output any = resp
if typeof(output) == "number" {
output = newNumber().Set(output.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -387,10 +351,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
output = output.(number).Add(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Add__"]; ok { if y, ok := x.obj["__Add__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -400,11 +361,26 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if err.EXISTS { if !err.EXISTS {
return nil, err output = val
continue
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostAdd__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if !err.EXISTS {
output = val
continue
} }
output = val
continue
} }
} }
return nil, ArErr{ return nil, ArErr{
@@ -416,7 +392,7 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
true, true,
} }
} }
return (output), ArErr{} return output, ArErr{}
} }
func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
@@ -430,9 +406,6 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
var output any = resp var output any = resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
@@ -442,10 +415,7 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(output) == "number" && typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
output = output.(number).Mul(output.(number), resp.(number))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Multiply__"]; ok { if y, ok := x.obj["__Multiply__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -455,11 +425,26 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if err.EXISTS { if !err.EXISTS {
return nil, err output = val
continue
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostMultiply__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if !err.EXISTS {
output = val
continue
} }
output = val
continue
} }
} }
return nil, ArErr{ return nil, ArErr{
@@ -483,7 +468,7 @@ func calcAnd(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -503,7 +488,7 @@ func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -539,7 +524,7 @@ func calcNotIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
@@ -624,9 +609,7 @@ func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
} }
} }
func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) { func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
if typeof(a) == "number" && typeof(b) == "number" { if x, ok := a.(ArObject); ok {
return a.(number).Cmp(b.(number)) != 0, ArErr{}
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__NotEqual__"]; ok { if y, ok := x.obj["__NotEqual__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -662,9 +645,7 @@ func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool
func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) { func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, ArErr) {
debugPrintln("equals", a, b) debugPrintln("equals", a, b)
if typeof(a) == "number" && typeof(b) == "number" { if x, ok := a.(ArObject); ok {
return a.(number).Cmp(b.(number)) == 0, ArErr{}
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__Equal__"]; ok { if y, ok := x.obj["__Equal__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -708,27 +689,16 @@ func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" && typeof(output) == "number" { if x, ok := output.(ArObject); ok {
x := newNumber().Set(resp.(number))
x.Quo(output.(number), x)
x = floor(x)
x.Mul(x, resp.(number))
output.(number).Sub(output.(number), x)
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Modulo__"]; ok { if y, ok := x.obj["__Modulo__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -767,23 +737,17 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
return nil, err return nil, err
} }
output := resp output := resp
if isAnyNumber(resp) {
output = newNumber().Set(resp.(number))
}
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" && typeof(output) == "number" { if x, ok := output.(ArObject); ok {
output = floor(output.(number).Quo(output.(number), resp.(number)))
continue
} else if x, ok := output.(ArObject); ok {
if y, ok := x.obj["__IntDivide__"]; ok { if y, ok := x.obj["__IntDivide__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
@@ -802,7 +766,7 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
} }
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot divide type '" + typeof(resp) + "'", "Cannot int divide type '" + typeof(resp) + "'",
o.line, o.line,
o.path, o.path,
o.code, o.code,
@@ -812,93 +776,142 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
return output, ArErr{} return output, ArErr{}
} }
func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) { // func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
// resp, err := runVal(
// o.values[0],
// stack,
// stacklevel+1,
// )
//
// if err.EXISTS {
// return nil, err
// }
// if typeof(resp) != "number" {
// return nil, ArErr{
// "Runtime Error",
// "Cannot calculate power of type '" + typeof(resp) + "'",
// o.line,
// o.path,
// o.code,
// true,
// }
// }
// output := newNumber().Set(resp.(number))
// for i := 1; i < len(o.values); i++ {
// resp, err := runVal(
// o.values[i],
// stack,
// stacklevel+1,
// )
//
// if err.EXISTS {
// return nil, err
// }
// if typeof(resp) == "number" {
// n := newNumber().Set(resp.(number))
// if n.Cmp(newNumber().SetInt64(10)) <= 0 {
// toOut := newNumber().SetInt64(1)
// clone := newNumber().Set(output)
// nAbs := (abs(newNumber().Set(n)))
// j := newNumber()
// for ; j.Cmp(nAbs) < 0; j.Add(j, one) {
// toOut.Mul(toOut, clone)
// }
// nAbs.Sub(nAbs, j)
// if nAbs.Cmp(newNumber()) < 0 {
// j.Sub(j, one)
// n1, _ := toOut.Float64()
// n2, _ := nAbs.Float64()
// calculated := newNumber().SetFloat64(math.Pow(n1, n2))
// if calculated == nil {
// calculated = infinity
// }
// toOut.Mul(toOut, calculated)
// }
// if n.Cmp(newNumber()) < 0 {
// toOut.Quo(newNumber().SetInt64(1), toOut)
// }
// output.Set(toOut)
// } else if n.Cmp(newNumber().SetInt64(1)) != 0 {
// n1, _ := output.Float64()
// n2, _ := n.Float64()
// calculated := newNumber().SetFloat64(math.Pow(n1, n2))
// if calculated == nil {
// calculated = infinity
// }
// output.Mul(output, calculated)
// }
// /*
// n1, _ := output.Float64()
// n2, _ := resp.(number).Float64()
// output = newNumber().SetFloat64(math.Pow(n1, n2))
// if output == nil {
// output = infinity
// }
// */
// } else {
// return nil, ArErr{
// "Runtime Error",
// "Cannot calculate power of type '" + typeof(resp) + "'",
// o.line,
// o.path,
// o.code,
// true,
// }
// }
// }
// return output, ArErr{}
// }
func calcPower(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.values[0],
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) != "number" { var output any = resp
return nil, ArErr{
"Runtime Error",
"Cannot calculate power of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
}
output := newNumber().Set(resp.(number))
for i := 1; i < len(o.values); i++ { for i := 1; i < len(o.values); i++ {
resp, err := runVal( resp, err := runVal(
o.values[i], o.values[i],
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if typeof(resp) == "number" { if x, ok := output.(ArObject); ok {
n := newNumber().Set(resp.(number)) if y, ok := x.obj["__Power__"]; ok {
if n.Cmp(newNumber().SetInt64(10)) <= 0 { val, err := runCall(
toOut := newNumber().SetInt64(1) call{
clone := newNumber().Set(output) y,
nAbs := (abs(newNumber().Set(n))) []any{resp},
j := newNumber() o.code,
for ; j.Cmp(nAbs) < 0; j.Add(j, one) { o.line,
toOut.Mul(toOut, clone) o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
} }
output = val
nAbs.Sub(nAbs, j) continue
if nAbs.Cmp(newNumber()) < 0 {
j.Sub(j, one)
n1, _ := toOut.Float64()
n2, _ := nAbs.Float64()
calculated := newNumber().SetFloat64(math.Pow(n1, n2))
if calculated == nil {
calculated = infinity
}
toOut.Mul(toOut, calculated)
}
if n.Cmp(newNumber()) < 0 {
toOut.Quo(newNumber().SetInt64(1), toOut)
}
output.Set(toOut)
} else if n.Cmp(newNumber().SetInt64(1)) != 0 {
n1, _ := output.Float64()
n2, _ := n.Float64()
calculated := newNumber().SetFloat64(math.Pow(n1, n2))
if calculated == nil {
calculated = infinity
}
output.Mul(output, calculated)
}
/*
n1, _ := output.Float64()
n2, _ := resp.(number).Float64()
output = newNumber().SetFloat64(math.Pow(n1, n2))
if output == nil {
output = infinity
}
*/
} else {
return nil, ArErr{
"Runtime Error",
"Cannot calculate power of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
} }
} }
return nil, ArErr{
"Runtime Error",
"Cannot power type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
o.line,
o.path,
o.code,
true,
}
} }
return output, ArErr{} return (output), ArErr{}
} }
func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) { func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
@@ -918,9 +931,9 @@ func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
case 11: case 11:
return calcNegative(o, stack, stacklevel+1) return calcNegative(o, stack, stacklevel+1)
case 12: case 12:
return calcMod(o, stack, stacklevel+1)
case 13:
return calcMul(o, stack, stacklevel+1) return calcMul(o, stack, stacklevel+1)
case 13:
return calcMod(o, stack, stacklevel+1)
case 14: case 14:
return calcIntDiv(o, stack, stacklevel+1) return calcIntDiv(o, stack, stacklevel+1)
case 15: case 15:

View File

@@ -1,49 +0,0 @@
package main
import (
"fmt"
"runtime"
"time"
"github.com/shirou/gopsutil/cpu"
)
var platform = Map(
anymap{
"os": ArString(runtime.GOOS),
"cpu": Map(anymap{
"count": newNumber().SetInt64((int64)(runtime.NumCPU())),
"usage": builtinFunc{"usage", func(args ...any) (any, ArErr) {
if len(args) != 2 {
return nil, ArErr{
TYPE: "Runtime Error",
message: "usage takes 2 arguments, got " + fmt.Sprint(len(args)),
EXISTS: true,
}
}
if !isAnyNumber(args[0]) {
return nil, ArErr{
TYPE: "Runtime Error",
message: "first argument is meant to be a number, got " + fmt.Sprint(typeof(args[0])),
EXISTS: true,
}
}
var Number = newNumber().Mul(args[0].(number), newNumber().SetInt64(1000)).Num().Int64()
avgPercent, err := cpu.Percent(time.Duration(Number)*time.Millisecond, anyToBool(args[1]))
if err != nil {
return nil, ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
var ArAvgPercent = []any{}
for i := 0; i < len(avgPercent); i++ {
ArAvgPercent = append(ArAvgPercent, newNumber().SetFloat64(avgPercent[i]))
}
return ArArray(ArAvgPercent), ArErr{}
}},
}),
},
)

View File

@@ -6,10 +6,10 @@ import (
"time" "time"
) )
func random() number { var rand_source = rand.New(rand.NewSource(time.Now().UnixMicro()))
return newNumber().SetFloat64(
rand.Float64(), func random() ArObject {
) return Number(rand_source.Float64())
} }
func randomRange(args ...any) (any, ArErr) { func randomRange(args ...any) (any, ArErr) {
@@ -33,23 +33,88 @@ func randomRange(args ...any) (any, ArErr) {
EXISTS: true, EXISTS: true,
} }
} }
min := args[0].(number) min := args[0].(ArObject)
max := args[1].(number) max := args[1].(ArObject)
if min.Cmp(max) > 0 {
compare_num, err := CompareObjects(min, max)
if err.EXISTS {
return nil, err
}
compare, Err := numberToInt64(compare_num)
if Err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Runtime Error", TYPE: "Runtime Error",
message: "takes a min less than max", message: Err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
difference := newNumber().Sub(max, min)
if compare == 1 {
return nil, ArErr{
TYPE: "Runtime Error",
message: "range() num 1 must be less than or equal to num 2",
EXISTS: true,
}
}
num_range, err := runOperation(
operationType{
operation: 11,
values: []any{max, min},
},
stack{},
0,
)
if err.EXISTS {
return nil, err
}
if _, ok := num_range.(ArObject); !ok {
return nil, ArErr{
TYPE: "Runtime Error",
message: "could not subtract the two numbers to calculate the range",
EXISTS: true,
}
}
num_range_obj := num_range.(ArObject)
rand := random() rand := random()
rand.Mul(rand, difference)
rand.Add(rand, min) multiplier, err := runOperation(
return rand, ArErr{} operationType{
operation: 12,
values: []any{rand, num_range_obj},
},
stack{},
0,
)
if err.EXISTS {
return nil, err
}
if _, ok := multiplier.(ArObject); !ok {
return nil, ArErr{
TYPE: "Runtime Error",
message: "could not multiply the random number by the range",
EXISTS: true,
}
}
return runOperation(
operationType{
operation: 10,
values: []any{multiplier, min},
},
stack{},
0,
)
} }
var ArRandom = Map(anymap{ var ArRandom = ArObject{anymap{
"__call__": builtinFunc{"random", func(args ...any) (any, ArErr) { "__call__": builtinFunc{"random", func(args ...any) (any, ArErr) {
if len(args) != 0 { if len(args) != 0 {
return nil, ArErr{ return nil, ArErr{
@@ -83,22 +148,15 @@ var ArRandom = Map(anymap{
EXISTS: true, EXISTS: true,
} }
} }
if !a[0].(number).IsInt() { new_seed, err := numberToInt64(a[0].(ArObject))
if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Runtime Error", TYPE: "Runtime Error",
message: "takes an integer not a float", message: err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
rand.Seed( rand_source.Seed(new_seed)
a[0].(number).Num().Int64(),
)
return nil, ArErr{} return nil, ArErr{}
}}, }},
}) }}
func initRandom() {
rand.Seed(
time.Now().UnixMicro(),
)
}

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"math/big"
"reflect" "reflect"
) )
@@ -56,30 +57,30 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
break break
} }
return setVariableValue(x, stack, stacklevel+1) return setVariableValue(x, stack, stacklevel+1)
case negative: // case negative:
if stackoverflow { // if stackoverflow {
linenum = x.line // linenum = x.line
path = x.path // path = x.path
code = x.code // code = x.code
break // break
} // }
resp, err := runVal(x.VAL, stack, stacklevel+1) // resp, err := runVal(x.VAL, stack, stacklevel+1)
resp = AnyToArValid(resp) // resp = AnyToArValid(resp)
if err.EXISTS { // if err.EXISTS {
return nil, err // return nil, err
} // }
switch y := resp.(type) { // switch y := resp.(type) {
case number: // case compiledNumber:
if !x.sign { // if !x.sign {
return newNumber().Neg(y), ArErr{} // return Number(compiledNumber{new(big.Rat).Neg(y)}), ArErr{}
} // }
return y, ArErr{} // return y, ArErr{}
} // }
return nil, ArErr{ // return nil, ArErr{
TYPE: "Type Error", // TYPE: "Type Error",
message: "cannot negate a non-number", // message: "cannot negate a non-number",
EXISTS: true, // EXISTS: true,
} // }
case operationType: case operationType:
if stackoverflow { if stackoverflow {
linenum = x.line linenum = x.line
@@ -208,7 +209,11 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
break break
} }
return runTryCatch(x, stack, stacklevel+1) return runTryCatch(x, stack, stacklevel+1)
case bool, ArObject, number, nil, Callable, builtinFunc, anymap: case compiledNumber:
return Number(x.value), ArErr{}
case int64, int, float64, float32, *big.Rat, *big.Int:
return Number(x), ArErr{}
case bool, ArObject, nil, Callable, builtinFunc, anymap:
return x, ArErr{} return x, ArErr{}
} }
if stackoverflow { if stackoverflow {
@@ -222,6 +227,7 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
} }
} }
fmt.Println("unreachable", reflect.TypeOf(line)) fmt.Println("unreachable", reflect.TypeOf(line))
fmt.Println(line)
panic("unreachable") panic("unreachable")
} }

View File

@@ -14,12 +14,12 @@ func shell(global ArObject) {
go func() { go func() {
for sig := range c { for sig := range c {
if sig == os.Interrupt { if sig == os.Interrupt {
fmt.Println("\x1b[0m\n\x1b[32;240mBye :)\x1b[0m") fmt.Println("\x1b[0m\n\x1b[32;5;240mBye :)\x1b[0m")
os.Exit(0) os.Exit(0)
} }
} }
}() }()
fmt.Print("\x1b[32;240mWelcome to the Argon v3!\x1b[0m\n\n") fmt.Print("\x1b[32;5;25mWelcome to the Argon v3!\x1b[25m\n\n")
for { for {
indent := 0 indent := 0
previous := 0 previous := 0
@@ -27,12 +27,12 @@ func shell(global ArObject) {
textBefore := ">>>" textBefore := ">>>"
for i := 1; indent > 0 || (previous != indent && indent >= 0) || i == 1; i++ { for i := 1; indent > 0 || (previous != indent && indent >= 0) || i == 1; i++ {
indentStr := strings.Repeat(" ", indent) indentStr := strings.Repeat(" ", indent)
inp, err := input("\x1b[38;240m" + textBefore + indentStr + " \x1b[0m") line, err := input("\x1b[38;5;240m" + textBefore + indentStr + " \x1b[0m\x1b[1;5;25m")
if err != nil { if err != nil {
fmt.Println("\x1b[0m\n\x1b[32;240mBye :)\x1b[0m") fmt.Println("\x1b[0m\n\x1b[32;5;25mBye :)\x1b[0m")
os.Exit(0) os.Exit(0)
} }
code := indentStr + inp code := indentStr + line
fmt.Print("\x1b[0m") fmt.Print("\x1b[0m")
totranslate = append(totranslate, UNPARSEcode{code, code, i, "<shell>"}) totranslate = append(totranslate, UNPARSEcode{code, code, i, "<shell>"})
trimmed := strings.TrimSpace(code) trimmed := strings.TrimSpace(code)

View File

@@ -226,15 +226,16 @@ func ArSocketServer(args ...any) (any, ArErr) {
} }
} }
networktype := ArValidToAny(args[0]).(string) networktype := ArValidToAny(args[0]).(string)
port := args[1].(number) port_num := args[1].(ArObject)
if port.Denom().Int64() != 1 { port, err := numberToInt64(port_num)
if err != nil {
return ArObject{}, ArErr{ return ArObject{}, ArErr{
TYPE: "Socket Error", TYPE: "Socket Error",
message: "Socket port must be an integer", message: err.Error(),
EXISTS: true, EXISTS: true,
} }
} }
ln, err := net.Listen(networktype, ":"+fmt.Sprint(port.Num().Int64())) ln, err := net.Listen(networktype, ":"+fmt.Sprint(port))
if err != nil { if err != nil {
return ArObject{}, ArErr{ return ArObject{}, ArErr{
TYPE: "Socket Error", TYPE: "Socket Error",

View File

@@ -58,9 +58,7 @@ func getkeyCache(getKey func(any) (any, ArErr), key any) (any, ArErr) {
} }
func compare(a, b any) (bool, error) { func compare(a, b any) (bool, error) {
if isAnyNumber(a) && isAnyNumber(b) { if x, ok := a.(ArObject); ok {
return a.(number).Cmp(b.(number)) < 0, nil
} else if x, ok := a.(ArObject); ok {
if y, ok := x.obj["__LessThan__"]; ok { if y, ok := x.obj["__LessThan__"]; ok {
resp, err := runCall( resp, err := runCall(
call{ call{

View File

@@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/fatih/color"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
) )
@@ -68,6 +69,32 @@ func ArString(str string) ArObject {
}, },
} }
obj.obj["__string__"] = builtinFunc{
"__string__",
func(a ...any) (any, ArErr) {
return str, ArErr{}
}}
obj.obj["__repr__"] = builtinFunc{
"__repr__",
func(a ...any) (any, ArErr) {
colored := false
if len(a) == 1 {
if typeof(a[0]) != "boolean" {
return nil, ArErr{"Type Error", "expected boolean, got " + typeof(a[0]), 0, "", "", true}
}
colored = a[0].(bool)
}
output := []string{}
quoted := strconv.Quote(str)
if colored {
output = append(output, color.New(33).Sprint(quoted))
} else {
output = append(output, quoted)
}
return ArString(strings.Join(output, "")), ArErr{}
},
}
obj.obj["__setindex__"] = builtinFunc{ obj.obj["__setindex__"] = builtinFunc{
"__setindex__", "__setindex__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {
@@ -124,14 +151,12 @@ func ArString(str string) ArObject {
{ {
if a[0] == nil { if a[0] == nil {
start = 0 start = 0
} else if typeof(a[0]) != "number" || !a[0].(number).IsInt() { } else if x, ok := a[0].(ArObject); ok {
return "", ArErr{ start64, err := numberToInt64(x)
TYPE: "Type Error", if err != nil {
message: "slice index must be an integer", return nil, ArErr{"Type Error", err.Error(), 0, "", "", true}
EXISTS: true,
} }
} else { start = int(start64)
start = int(a[0].(number).Num().Int64())
} }
} }
if len(a) > 1 { if len(a) > 1 {
@@ -629,10 +654,10 @@ func ArString(str string) ArObject {
} }
n := a[0].(number) n := a[0].(number)
if !n.IsInt() { if !n.IsInt() {
return nil, ArErr{"Value Error", "cannot multiply string by float", 0, "", "", true} return nil, ArErr{"ValueError", "cannot multiply string by float", 0, "", "", true}
} }
if n.Sign() < 0 { if n.Sign() < 0 {
return nil, ArErr{"Value Error", "cannot multiply string by negative number", 0, "", "", true} return nil, ArErr{"ValueError", "cannot multiply string by negative number", 0, "", "", true}
} }
return strings.Repeat(str, int(n.Num().Int64())), ArErr{} return strings.Repeat(str, int(n.Num().Int64())), ArErr{}
}} }}

View File

@@ -140,15 +140,11 @@ var ArInput = Map(
return ArString(resp), ArErr{} return ArString(resp), ArErr{}
}}, }},
"__call__": builtinFunc{"input", func(args ...any) (any, ArErr) { "__call__": builtinFunc{"input", func(args ...any) (any, ArErr) {
inp, err := input(args...) resp, err := input(args...)
if err != nil { if err != nil {
return nil, ArErr{ return nil, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
} }
return ArString(inp), ArErr{} return ArString(resp), ArErr{}
}}, }},
"pause": builtinFunc{"pause", func(args ...any) (any, ArErr) { "pause": builtinFunc{"pause", func(args ...any) (any, ArErr) {
pause() pause()

View File

@@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"math"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@@ -11,7 +10,7 @@ import (
"github.com/jwalton/go-supportscolor" "github.com/jwalton/go-supportscolor"
) )
func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored bool, plain int) string { func anyToArgon(x any, representive bool, simplify bool, depth int, indent int, colored bool, plain int) string {
output := []string{} output := []string{}
maybenewline := "" maybenewline := ""
if plain == 1 { if plain == 1 {
@@ -29,37 +28,9 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
return strings.Join(output, "") return strings.Join(output, "")
} }
switch x := x.(type) { switch x := x.(type) {
case string:
if !quote {
output = append(output, x)
break
}
quoted := strconv.Quote(x)
if colored {
output = append(output, color.New(33).Sprint(quoted))
} else {
output = append(output, quoted)
}
case number:
if colored {
output = append(output, "\x1b[34;240m")
}
num, _ := x.Float64()
if math.IsNaN(num) {
output = append(output, "NaN")
} else if math.IsInf(num, 1) {
output = append(output, "infinity")
} else if math.IsInf(num, -1) {
output = append(output, "-infinity")
} else {
output = append(output, numberToString(x, simplify))
}
if colored {
output = append(output, "\x1b[0m")
}
case bool: case bool:
if colored { if colored {
output = append(output, "\x1b[35;240m") output = append(output, "\x1b[35;5;25m")
} }
output = append(output, strconv.FormatBool(x)) output = append(output, strconv.FormatBool(x))
if colored { if colored {
@@ -67,14 +38,14 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} }
case nil: case nil:
if colored { if colored {
output = append(output, "\x1b[31;240m") output = append(output, "\x1b[31;5;25m")
} }
output = append(output, "null") output = append(output, "null")
if colored { if colored {
output = append(output, "\x1b[0m") output = append(output, "\x1b[0m")
} }
case ArObject: case ArObject:
if callable, ok := x.obj["__string__"]; ok && !quote { if callable, ok := x.obj["__string__"]; ok && !representive {
val, err := runCall( val, err := runCall(
call{ call{
Callable: callable, Callable: callable,
@@ -84,24 +55,24 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
0, 0,
) )
if !err.EXISTS { if !err.EXISTS {
output = append(output, anyToArgon(val, false, simplify, depth, indent, colored, plain)) output = append(output, fmt.Sprint(ArValidToAny(val)))
break break
} }
} else if callable, ok := x.obj["__repr__"]; ok { } else if callable, ok := x.obj["__repr__"]; ok {
val, err := runCall( val, err := runCall(
call{ call{
Callable: callable, Callable: callable,
Args: []any{}, Args: []any{colored},
}, },
stack{}, stack{},
0, 0,
) )
if !err.EXISTS { if !err.EXISTS {
output = append(output, anyToArgon(val, false, simplify, depth, indent, colored, plain)) output = append(output, fmt.Sprint(ArValidToAny(val)))
break break
} }
} else if val, ok := x.obj["__value__"]; ok { } else if val, ok := x.obj["__value__"]; ok {
output = append(output, anyToArgon(val, quote, simplify, depth, indent, colored, plain)) output = append(output, anyToArgon(val, representive, simplify, depth, indent, colored, plain))
break break
} }
output = append(output, "<object>") output = append(output, "<object>")
@@ -128,7 +99,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} else { } else {
outputkeyval := []string{} outputkeyval := []string{}
if colored { if colored {
outputkeyval = append(outputkeyval, "\x1b[36;240m") outputkeyval = append(outputkeyval, "\x1b[36;5;25m")
} }
outputkeyval = append(outputkeyval, key.(string)) outputkeyval = append(outputkeyval, key.(string))
if colored { if colored {
@@ -148,7 +119,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
output = append(output, anyToArgon(item, true, true, depth-1, indent+1, colored, plain)) output = append(output, anyToArgon(item, true, true, depth-1, indent+1, colored, plain))
} }
if colored { if colored {
output = append(output, "\x1b[38;240m(...)\x1b[0m") output = append(output, "\x1b[38;5;25m(...)\x1b[0m")
} else { } else {
output = append(output, "(...)") output = append(output, "(...)")
} }
@@ -173,7 +144,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
return "[" + maybenewline + (strings.Repeat(" ", (indent+1)*plain)) + strings.Join(output, ","+maybenewline+(strings.Repeat(" ", (indent+1)*plain))) + maybenewline + (strings.Repeat(" ", indent*plain)) + "]" return "[" + maybenewline + (strings.Repeat(" ", (indent+1)*plain)) + strings.Join(output, ","+maybenewline+(strings.Repeat(" ", (indent+1)*plain))) + maybenewline + (strings.Repeat(" ", indent*plain)) + "]"
case builtinFunc: case builtinFunc:
if colored { if colored {
output = append(output, "\x1b[38;240m") output = append(output, "\x1b[38;5;25m")
} }
output = append(output, "<builtin function "+x.name+">") output = append(output, "<builtin function "+x.name+">")
if colored { if colored {
@@ -181,7 +152,7 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
} }
case Callable: case Callable:
if colored { if colored {
output = append(output, "\x1b[38;240m") output = append(output, "\x1b[38;5;25m")
} }
output = append(output, "<function "+x.name+">") output = append(output, "<function "+x.name+">")
if colored { if colored {

View File

@@ -103,13 +103,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
} }
QuickKnownFailures["squareroot"+code.code] = true QuickKnownFailures["squareroot"+code.code] = true
} }
if !QuickKnownFailures["factorial"+code.code] && isFactorial(code) {
resp, worked, err, i = parseFactorial(code, index, codelines)
if worked {
return resp, worked, err, i
}
QuickKnownFailures["factorial"+code.code] = true
}
if isVariable(code) { if isVariable(code) {
return parseVariable(code) return parseVariable(code)
} }
@@ -139,8 +132,12 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return nil, worked, err, step return nil, worked, err, step
} }
} }
if isNegative(code) { if !QuickKnownFailures["factorial"+code.code] && isFactorial(code) {
return parseNegative(code, index, codelines) resp, worked, err, i = parseFactorial(code, index, codelines)
if worked {
return resp, worked, err, i
}
QuickKnownFailures["factorial"+code.code] = true
} }
if !QuickKnownFailures["call"+code.code] && isCall(code) { if !QuickKnownFailures["call"+code.code] && isCall(code) {
resp, worked, err, i = parseCall(code, index, codelines) resp, worked, err, i = parseCall(code, index, codelines)
@@ -149,7 +146,9 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
} }
QuickKnownFailures["call"+code.code] = true QuickKnownFailures["call"+code.code] = true
} }
if isMapGet(code) { if isNegative(code) {
return parseNegative(code, index, codelines)
} else if isMapGet(code) {
return mapGetParse(code, index, codelines) return mapGetParse(code, index, codelines)
} else if !QuickKnownFailures["indexget"+code.code] && isIndexGet(code) { } else if !QuickKnownFailures["indexget"+code.code] && isIndexGet(code) {
resp, worked, err, i = indexGetParse(code, index, codelines) resp, worked, err, i = indexGetParse(code, index, codelines)

View File

@@ -14,9 +14,9 @@ type sinCacheValue struct {
var sinCache = []sinCacheValue{ var sinCache = []sinCacheValue{
{newNumber(), newNumber()}, {newNumber(), newNumber()},
{newNumber().Quo(PI, newNumber().SetInt64(2)), newNumber().SetInt64(1)}, {newNumber().Quo(PI_RAT, newNumber().SetInt64(2)), newNumber().SetInt64(1)},
{PI, newNumber()}, {PI_RAT, newNumber()},
{newNumber().Add(PI, newNumber().Quo(PI, newNumber().SetInt64(2))), newNumber().SetInt64(-1)}, {newNumber().Add(PI_RAT, newNumber().Quo(PI_RAT, newNumber().SetInt64(2))), newNumber().SetInt64(-1)},
} }
func init() { func init() {
@@ -37,10 +37,10 @@ var ArSin = builtinFunc{"sin", func(args ...any) (any, ArErr) {
} }
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
toTrim := newNumber().Mul(PI, newNumber().SetInt64(2)) toTrim := newNumber().Mul(PI_RAT, newNumber().SetInt64(2))
toTrim.Quo(num, toTrim) toTrim.Quo(num, toTrim)
toTrim = floor(toTrim) toTrim = floor(toTrim)
toTrim.Mul(toTrim, newNumber().Mul(PI, newNumber().SetInt64(2))) toTrim.Mul(toTrim, newNumber().Mul(PI_RAT, newNumber().SetInt64(2)))
num.Sub(num, toTrim) num.Sub(num, toTrim)
for i := 0; i < len(sinCache); i++ { for i := 0; i < len(sinCache); i++ {
@@ -49,7 +49,7 @@ var ArSin = builtinFunc{"sin", func(args ...any) (any, ArErr) {
} }
} }
num.Quo(num, PI) num.Quo(num, PI_RAT)
num.Mul(num, PIFloatInaccuracy) num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64() n, _ := num.Float64()
outputnum := newNumber().SetFloat64(math.Sin(n)) outputnum := newNumber().SetFloat64(math.Sin(n))
@@ -78,7 +78,7 @@ var ArArcsin = builtinFunc{"arcsin", func(args ...any) (any, ArErr) {
} }
outputnum := newNumber().SetFloat64(math.Asin(n)) outputnum := newNumber().SetFloat64(math.Asin(n))
outputnum.Quo(outputnum, PIFloatInaccuracy) outputnum.Quo(outputnum, PIFloatInaccuracy)
outputnum.Mul(outputnum, PI) outputnum.Mul(outputnum, PI_RAT)
return outputnum, ArErr{} return outputnum, ArErr{}
}} }}
@@ -95,7 +95,7 @@ var ArCos = builtinFunc{"cos", func(args ...any) (any, ArErr) {
EXISTS: true, EXISTS: true,
} }
} }
return builtinCall(ArSin, []any{newNumber().Add(args[0].(number), newNumber().Quo(PI, newNumber().SetInt64(2)))}) return builtinCall(ArSin, []any{newNumber().Add(args[0].(number), newNumber().Quo(PI_RAT, newNumber().SetInt64(2)))})
}} }}
var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) { var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) {
if len(args) != 1 { if len(args) != 1 {
@@ -120,7 +120,7 @@ var ArArccos = builtinFunc{"arccos", func(args ...any) (any, ArErr) {
} }
outputnum := newNumber().SetFloat64(math.Acos(n)) outputnum := newNumber().SetFloat64(math.Acos(n))
outputnum.Quo(outputnum, PIFloatInaccuracy) outputnum.Quo(outputnum, PIFloatInaccuracy)
outputnum.Mul(outputnum, PI) outputnum.Mul(outputnum, PI_RAT)
return outputnum, ArErr{} return outputnum, ArErr{}
}} }}
@@ -138,7 +138,7 @@ var ArTan = builtinFunc{"tan", func(args ...any) (any, ArErr) {
} }
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
num.Quo(num, PI) num.Quo(num, PI_RAT)
num.Mul(num, PIFloatInaccuracy) num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64() n, _ := num.Float64()
outputnum := newNumber().SetFloat64(math.Tan(n)) outputnum := newNumber().SetFloat64(math.Tan(n))
@@ -161,7 +161,7 @@ var ArArctan = builtinFunc{"arctan", func(args ...any) (any, ArErr) {
n, _ := num.Float64() n, _ := num.Float64()
outputnum := newNumber().SetFloat64(math.Atan(n)) outputnum := newNumber().SetFloat64(math.Atan(n))
outputnum.Quo(outputnum, PIFloatInaccuracy) outputnum.Quo(outputnum, PIFloatInaccuracy)
outputnum.Mul(outputnum, PI) outputnum.Mul(outputnum, PI_RAT)
return outputnum, ArErr{} return outputnum, ArErr{}
}} }}
@@ -179,7 +179,7 @@ var ArCosec = builtinFunc{"cosec", func(args ...any) (any, ArErr) {
} }
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
num.Quo(num, PI) num.Quo(num, PI_RAT)
num.Mul(num, PIFloatInaccuracy) num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64() n, _ := num.Float64()
outputnum := newNumber().SetFloat64(1 / math.Sin(n)) outputnum := newNumber().SetFloat64(1 / math.Sin(n))
@@ -208,7 +208,7 @@ var ArArccosec = builtinFunc{"arccosec", func(args ...any) (any, ArErr) {
} }
outputnum := newNumber().SetFloat64(math.Asin(1 / n)) outputnum := newNumber().SetFloat64(math.Asin(1 / n))
outputnum.Quo(outputnum, PIFloatInaccuracy) outputnum.Quo(outputnum, PIFloatInaccuracy)
outputnum.Mul(outputnum, PI) outputnum.Mul(outputnum, PI_RAT)
return outputnum, ArErr{} return outputnum, ArErr{}
}} }}
@@ -226,7 +226,7 @@ var ArSec = builtinFunc{"sec", func(args ...any) (any, ArErr) {
} }
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
num.Quo(num, PI) num.Quo(num, PI_RAT)
num.Mul(num, PIFloatInaccuracy) num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64() n, _ := num.Float64()
outputnum := newNumber().SetFloat64(1 / math.Cos(n)) outputnum := newNumber().SetFloat64(1 / math.Cos(n))
@@ -256,7 +256,7 @@ var ArArcsec = builtinFunc{"arcsec", func(args ...any) (any, ArErr) {
} }
outputnum := newNumber().SetFloat64(math.Acos(1 / n)) outputnum := newNumber().SetFloat64(math.Acos(1 / n))
outputnum.Quo(outputnum, PIFloatInaccuracy) outputnum.Quo(outputnum, PIFloatInaccuracy)
outputnum.Mul(outputnum, PI) outputnum.Mul(outputnum, PI_RAT)
return outputnum, ArErr{} return outputnum, ArErr{}
}} }}
@@ -274,7 +274,7 @@ var ArCot = builtinFunc{"cot", func(args ...any) (any, ArErr) {
} }
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
num.Quo(num, PI) num.Quo(num, PI_RAT)
num.Mul(num, PIFloatInaccuracy) num.Mul(num, PIFloatInaccuracy)
n, _ := num.Float64() n, _ := num.Float64()
outputnum := newNumber().SetFloat64(1 / math.Tan(n)) outputnum := newNumber().SetFloat64(1 / math.Tan(n))
@@ -298,7 +298,7 @@ var ArArccot = builtinFunc{"arccot", func(args ...any) (any, ArErr) {
n, _ := num.Float64() n, _ := num.Float64()
outputnum := newNumber().SetFloat64(math.Atan(1 / n)) outputnum := newNumber().SetFloat64(math.Atan(1 / n))
outputnum.Quo(outputnum, PIFloatInaccuracy) outputnum.Quo(outputnum, PIFloatInaccuracy)
outputnum.Mul(outputnum, PI) outputnum.Mul(outputnum, PI_RAT)
return outputnum, ArErr{} return outputnum, ArErr{}
}} }}
@@ -316,7 +316,7 @@ var ArToDeg = builtinFunc{"toDeg", func(args ...any) (any, ArErr) {
} }
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
num.Quo(num, PI) num.Quo(num, PI_RAT)
num.Mul(num, newNumber().SetInt64(180)) num.Mul(num, newNumber().SetInt64(180))
return num, ArErr{} return num, ArErr{}
}} }}
@@ -336,6 +336,6 @@ var ArToRad = builtinFunc{"toRad", func(args ...any) (any, ArErr) {
} }
num := newNumber().Set(args[0].(number)) num := newNumber().Set(args[0].(number))
num.Quo(num, newNumber().SetInt64(180)) num.Quo(num, newNumber().SetInt64(180))
num.Mul(num, PI) num.Mul(num, PI_RAT)
return num, ArErr{} return num, ArErr{}
}} }}

View File

@@ -2,8 +2,6 @@ package main
func typeof(val any) string { func typeof(val any) string {
switch x := val.(type) { switch x := val.(type) {
case number:
return "number"
case nil: case nil:
return "null" return "null"
case bool: case bool:

View File

@@ -76,12 +76,13 @@ func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
} }
func readVariable(v accessVariable, stack stack) (any, ArErr) { func readVariable(v accessVariable, stack stack) (any, ArErr) {
name := ArString(v.Name)
for i := len(stack) - 1; i >= 0; i-- { for i := len(stack) - 1; i >= 0; i-- {
callable, ok := stack[i].obj["__Contains__"] callable, ok := stack[i].obj["__Contains__"]
if !ok { if !ok {
continue continue
} }
contains, err := builtinCall(callable, []any{v.Name}) contains, err := builtinCall(callable, []any{name})
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -90,7 +91,7 @@ func readVariable(v accessVariable, stack stack) (any, ArErr) {
if !ok { if !ok {
continue continue
} }
return builtinCall(callable, []any{v.Name}) return builtinCall(callable, []any{name})
} }
} }
return nil, ArErr{"Name Error", "variable \"" + v.Name + "\" does not exist", v.Line, v.Path, v.Code, true} return nil, ArErr{"Name Error", "variable \"" + v.Name + "\" does not exist", v.Line, v.Path, v.Code, true}
@@ -159,7 +160,7 @@ func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine i
params = x.params params = x.params
toset = x.toset toset = x.toset
if toset == nil { if toset == nil {
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean to put 'let' before?", code.line, code.path, code.realcode, true}, 1 return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
} }
default: default:
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1 return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
@@ -223,7 +224,7 @@ func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, is
toset = x.toset toset = x.toset
default: default:
if i == len(equalsplit)-1 { if i == len(equalsplit)-1 {
return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean to put 'let' before?", code.line, code.path, code.realcode, true}, 1 return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", code.line, code.path, code.realcode, true}, 1
} }
continue continue
} }

View File

@@ -1,45 +1,33 @@
let brainfuck(INPUT) = do let interpret(code) = do
memory = [0] * 30*1000 memory = map()
pointer = 0 pointer = 0
output = "" code_ptr = 0
i = 0 loops = []
while (i < INPUT.length) do
if (INPUT[i] == ">") do
pointer += 1
else if (INPUT[i] == "<") do
pointer -= 1
else if (INPUT[i] == "+") do
memory[pointer] += 1
else if (INPUT[i] == "-") do
memory[pointer] -= 1
else if (INPUT[i] == ".") do
output += chr(memory[pointer])
else if (INPUT[i] == ",") do
memory[pointer] = ord(input())
else if (INPUT[i] == "[") do
if (memory[pointer] == 0) do
count = 1
while (count > 0) do
i += 1
if (INPUT[i] == "[") do
count += 1
else if (INPUT[i] == "]") do
count -= 1
else if (INPUT[i] == "]") do
if (memory[pointer] != 0) do
count = 1
while (count > 0) do
i -= 1
if (INPUT[i] == "]") do
count += 1
else if (INPUT[i] == "[") do
count -= 1
else do
pass
i += 1
term.print(memory)
return output
term.time("brainfuck") while (code_ptr < code.length) do
term.plain.oneLine(brainfuck(input())) command = code[code_ptr]
term.timeEnd("brainfuck")
if (command == '>') pointer = pointer + 1
else if (command == '<') pointer = pointer - 1
else if (command == '+') do
if (pointer not in memory) memory[pointer] = 0
memory[pointer] = memory[pointer] + 1
else if (command == '-') do
if (pointer not in memory) memory[pointer] = 0
memory[pointer] = memory[pointer] - 1
else if (command == '.') term.log((memory.get(pointer, 0)))
else if (command == ',') memory[pointer] = ord(input())
else if (command == '[') do
if (memory.get(pointer, 0) == 0) do
loop_depth = 1
while (loop_depth > 0) do
code_ptr = code_ptr + 1
if (code[code_ptr] == '[') loop_depth = loop_depth + 1
else if (code[code_ptr] == ']') loop_depth = loop_depth - 1
else loops.append(code_ptr)
else if (command == ']') do
if (memory.get(pointer, 0) != 0) code_ptr = loops[-1]
else loops.pop()
code_ptr = code_ptr + 1
interpret('>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.')