9 Commits

45 changed files with 890 additions and 2630 deletions

View File

@@ -1,2 +1,2 @@
@echo off @echo off
go build -trimpath -ldflags="-s -w" -o bin/argon.exe ./src go build -trimpath -ldflags="-s -w" -tags WINDOWS -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 ./src %* go run -tags WINDOWS ./src %*

7
go.mod
View File

@@ -9,7 +9,12 @@ 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 (
@@ -21,7 +26,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.6.0 // indirect golang.org/x/sys v0.19.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,6 +6,8 @@ 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=
@@ -15,12 +17,21 @@ 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=
@@ -29,6 +40,8 @@ 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,7 +17,12 @@ 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
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)`. ### Windows
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

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

View File

@@ -1 +0,0 @@
[{"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,28 +40,38 @@ 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) {
value, err := runVal(x, stack, stacklevel+1) resp, err := runVal(x.body, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
switch value := value.(type) { if typeof(resp) != "number" {
case ArObject: return nil, ArErr{TYPE: "Runtime Error",
if Callable, ok := value.obj["__abs__"]; ok { message: fmt.Sprintf("abs expected number, got %s", typeof(resp)),
return runCall(call{ EXISTS: true,
Callable: Callable,
Args: []any{},
Code: x.code,
Line: x.line,
Path: x.path,
}, stack, stacklevel)
} }
} }
return nil, ArErr{ return abs(resp.(number)), 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,48 +25,6 @@ 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) {
@@ -84,22 +42,14 @@ func ArArray(arr []any) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
if !isNumberInt(a[0].(ArObject)) { if !a[0].(number).IsInt() {
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,
} }
} }
num64, err := numberToInt64(a[0].(ArObject)) num := int(a[0].(number).Num().Int64())
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",
@@ -111,6 +61,29 @@ 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) {
@@ -125,7 +98,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 Number(len(arr)), ArErr{} return newNumber().SetInt64(int64(len(arr))), ArErr{}
} }
} }
} }
@@ -138,64 +111,40 @@ func ArArray(arr []any) ArObject {
{ {
if a[0] == nil { if a[0] == nil {
start = 0 start = 0
} else if typeof(a[0]) != "number" || !isNumberInt(a[0].(ArObject)) { } else if typeof(a[0]) != "number" || !a[0].(number).IsInt() {
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 {
start64, err := numberToInt64(a[0].(ArObject)) start = int(a[0].(number).Num().Int64())
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" || !isNumberInt(a[1].(ArObject)) { } else if typeof(a[1]) != "number" || !a[1].(number).IsInt() {
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 {
end64, err := numberToInt64(a[1].(ArObject)) end = int(a[1].(number).Num().Int64())
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" || !isNumberInt(a[2].(ArObject)) { } else if typeof(a[2]) != "number" || !a[2].(number).IsInt() {
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 {
step64, err := numberToInt64(a[2].(ArObject)) step = int(a[2].(number).Num().Int64())
if err != nil {
return "", ArErr{
TYPE: "Runtime Error",
message: err.Error(),
EXISTS: true,
}
}
step = int(step64)
} }
} }
var ogStart = start var ogStart = start
@@ -250,22 +199,14 @@ func ArArray(arr []any) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
if !isNumberInt(args[0].(ArObject)) { if !args[0].(number).IsInt() {
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,
} }
} }
num64, err := (numberToInt64(args[0].(ArObject))) num := int(args[0].(number).Num().Int64())
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",
@@ -309,22 +250,14 @@ func ArArray(arr []any) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
if !isNumberInt(args[0].(ArObject)) { if !args[0].(number).IsInt() {
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,
} }
} }
num64, err := numberToInt64(args[0].(ArObject)) num := int(args[0].(number).Num().Int64())
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",
@@ -355,22 +288,14 @@ func ArArray(arr []any) ArObject {
EXISTS: true, EXISTS: true,
} }
} }
if !isNumberInt(args[0].(ArObject)) { if !args[0].(number).IsInt() {
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,
} }
} }
num64, err := (numberToInt64(args[0].(ArObject))) num := int(args[0].(number).Num().Int64())
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",
@@ -572,7 +497,7 @@ func ArArray(arr []any) ArObject {
} }
if len(arr) == 0 { if len(arr) == 0 {
return nil, ArErr{ return nil, ArErr{
TYPE: "ValueError", TYPE: "Value Error",
message: "array is empty", message: "array is empty",
EXISTS: true, EXISTS: true,
} }

View File

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

View File

@@ -9,6 +9,7 @@ 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"] = newNumber().SetInt64(VERSION_NUM)
@@ -18,6 +19,7 @@ func makeGlobal() ArObject {
"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 {
@@ -66,7 +68,7 @@ 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 number:
if x.Denom().Cmp(_one_Rat.Denom()) != 0 { if x.Denom().Cmp(one.Denom()) != 0 {
return nil, ArErr{TYPE: "Type Error", message: "Cannot convert non-integer to hex", EXISTS: true} return nil, ArErr{TYPE: "Type Error", message: "Cannot convert non-integer to hex", EXISTS: true}
} }
n := x.Num().Int64() n := x.Num().Int64()
@@ -192,6 +194,7 @@ 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",
@@ -227,7 +230,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, AnyToArValid(key)) newarray = append(newarray, key)
} }
return ArArray(newarray), ArErr{} return ArArray(newarray), ArErr{}
} }
@@ -250,10 +253,9 @@ 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 int64: case number:
return string([]rune{rune(x)}), ArErr{} return string([]rune{rune(floor(x).Num().Int64())}), 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}
}} }}
@@ -265,7 +267,7 @@ 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(a)), EXISTS: true} return nil, ArErr{TYPE: "ord", message: "ord takes a string with only one character, got " + fmt.Sprint(len(x)), EXISTS: true}
} }
return floor(newNumber().SetInt64(int64([]rune(x)[0]))), ArErr{} return floor(newNumber().SetInt64(int64([]rune(x)[0]))), ArErr{}
} }

View File

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

View File

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

View File

@@ -28,26 +28,36 @@ 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 val := val.(type) { switch x := val.(type) {
case ArObject: case number:
if callable, ok := val.obj["__factorial__"]; ok { if !x.IsInt() {
return runCall(call{ return nil, ArErr{"Runtime Error", "cannot use factorial on non-integer", f.line, f.path, f.code, true}
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{ return fact(x), ArErr{}
TYPE: "TypeError", default:
message: "factorial not defined for type", return nil, ArErr{"Runtime Error", "cannot use factorial on non-number of type '" + typeof(val) + "'", f.line, f.path, f.code, true}
EXISTS: true,
} }
} }

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 = _one_Number stepval = newNumber().SetInt64(1)
} }
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.(ArObject) from := fromval.(number)
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.(ArObject) to := toval.(number)
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,16 +99,11 @@ 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.(ArObject) step := stepval.(number)
if isNumberInt64(from) && isNumberInt64(to) && isNumberInt64(step) { for i := newNumber().Set(from); i.Cmp(to) == -1; i = i.Add(i, step) {
i, _ := numberToInt64(from) resp, err := runVal(loop.body, append(stack, Map(anymap{
to_, _ := numberToInt64(to) loop.variable: newNumber().Set(i),
step_, _ := numberToInt64(step) })), stacklevel+1)
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 { if err.EXISTS {
return nil, err return nil, err
} }
@@ -118,58 +113,7 @@ 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 += 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 {
return nil, err
}
switch x := resp.(type) {
case Return:
return x, ArErr{}
case Break:
return nil, ArErr{}
case 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,10 +123,19 @@ 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 {
switch val.(type) { keytype := typeof(val)
case int64, float64, string, bool, nil: for _, v := range hashabletypes {
if v == keytype {
return false return false
} }
}
return true return true
} }

View File

@@ -156,6 +156,7 @@ 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,59 +2,13 @@ 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()))

55
src/input_unix.go Normal file
View File

@@ -0,0 +1,55 @@
//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
}

63
src/input_windows.go Normal file
View File

@@ -0,0 +1,63 @@
//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,7 +3,9 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"math"
"strconv" "strconv"
"strings"
) )
func convertToArgon(obj any) any { func convertToArgon(obj any) any {
@@ -22,7 +24,7 @@ func convertToArgon(obj any) any {
case string: case string:
return ArString(x) return ArString(x)
case float64: case float64:
return Number(x) return newNumber().SetFloat64(x)
case bool: case bool:
return x return x
case nil: case nil:
@@ -34,37 +36,43 @@ 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 { 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}
}
return convertToArgon(jsonMap), ArErr{} return convertToArgon(jsonMap), ArErr{}
} }
func jsonstringify(obj any, level int64) (string, error) { func jsonstringify(obj any, level int) (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 ArObject: case anymap:
if callable, ok := x.obj["__json__"]; ok { for key, value := range x {
val, err := runCall( str, err := jsonstringify(value, level+1)
call{ if err != nil {
Callable: callable, return "", err
Args: []any{Int64ToNumber(level)},
},
stack{},
0,
)
if err.EXISTS {
return "", errors.New(err.message)
} }
val = ArValidToAny(val) output = append(output, ""+strconv.Quote(anyToArgon(key, false, true, 3, 0, false, 0))+": "+str)
if x, ok := val.(string); ok {
return x, nil
} else {
return "", errors.New("json stringify error: __json__ must return a string")
} }
return "{" + strings.Join(output, ", ") + "}", nil
case []any:
for _, value := range x {
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:
@@ -86,21 +94,10 @@ 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) != 1 && len(args) != 2 { if len(args) == 0 {
return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 or 2 arguments", EXISTS: true} return nil, ArErr{TYPE: "Runtime Error", message: "stringify takes 1 argument", EXISTS: true}
} }
var level int64 = 0 str, err := jsonstringify(args[0], 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

@@ -15,6 +15,9 @@ func Ln(x number) number {
n1, _ := x.Float64() n1, _ := x.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

View File

@@ -10,8 +10,8 @@ var Args = os.Args[1:]
type stack = []ArObject type stack = []ArObject
const VERSION = "3.1.0 oop numbers beta 1" const VERSION = "3.0.11"
const VERSION_NUM = 7 const VERSION_NUM = 9
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 v" + VERSION + " that caused it to crash.") fmt.Println("There was a fundamental error in argon v3 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,6 +45,7 @@ func main() {
} }
}() }()
} }
initRandom()
garbageCollect() garbageCollect()
global := makeGlobal() global := makeGlobal()
if len(Args) == 0 { if len(Args) == 0 {

View File

@@ -245,7 +245,6 @@ 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,13 +1,5 @@
package main package main
import "math/big" var PI, _ = newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
var e, _ = newNumber().SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
var PI_RAT, _ = new(big.Rat).SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989") var infinity, _ = newNumber().SetString("1e1000")
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,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"math"
"reflect" "reflect"
"strings" "strings"
) )
@@ -19,13 +20,15 @@ var operations = []string{
"==", "==",
"+", "+",
"-", "-",
"*",
"%", "%",
"*",
"//", "//",
"/", "/",
"^", "^",
} }
var one = newNumber().SetInt64(1)
type operationType struct { type operationType struct {
operation int operation int
values []any values []any
@@ -71,7 +74,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 {
continue return operationType{}, success, err, 0
} }
values = append(values, resp) values = append(values, resp)
totalStep += respindex - 1 totalStep += respindex - 1
@@ -117,7 +120,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
} }
switch o.operation { switch o.operation {
case 4: case 4:
if x, ok := resp.(ArObject); ok { if isAnyNumber(resp) && isAnyNumber(resp2) {
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{
@@ -142,7 +147,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 5: case 5:
if x, ok := resp.(ArObject); ok { if isAnyNumber(resp) && isAnyNumber(resp2) {
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{
@@ -167,7 +174,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 6: case 6:
if x, ok := resp.(ArObject); ok { if isAnyNumber(resp) && isAnyNumber(resp2) {
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{
@@ -192,7 +201,9 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
true, true,
} }
case 7: case 7:
if x, ok := resp.(ArObject); ok { if isAnyNumber(resp) && isAnyNumber(resp2) {
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{
@@ -242,6 +253,9 @@ 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],
@@ -251,7 +265,10 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if x, ok := output.(ArObject); ok { if typeof(output) == "number" && typeof(resp) == "number" {
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{
@@ -292,17 +309,33 @@ 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 x, ok := output.(ArObject); ok { if typeof(resp) == "number" && typeof(output) == "number" {
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{
@@ -342,6 +375,9 @@ 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],
@@ -351,7 +387,10 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if x, ok := output.(ArObject); ok { if typeof(output) == "number" && typeof(resp) == "number" {
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{
@@ -361,28 +400,13 @@ 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 output = val
continue 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
}
}
}
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'", "Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
@@ -392,7 +416,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) {
@@ -406,6 +430,9 @@ 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],
@@ -415,7 +442,10 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
if x, ok := output.(ArObject); ok { if typeof(output) == "number" && typeof(resp) == "number" {
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{
@@ -425,28 +455,13 @@ 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 output = val
continue 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
}
}
}
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot multiply type '" + typeof(resp) + "'", "Cannot multiply type '" + typeof(resp) + "'",
@@ -468,7 +483,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
} }
@@ -488,7 +503,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
} }
@@ -524,7 +539,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
} }
@@ -609,7 +624,9 @@ 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 x, ok := a.(ArObject); ok { if typeof(a) == "number" && typeof(b) == "number" {
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{
@@ -645,7 +662,9 @@ 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 x, ok := a.(ArObject); ok { if typeof(a) == "number" && typeof(b) == "number" {
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{
@@ -689,16 +708,27 @@ 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 x, ok := output.(ArObject); ok { if typeof(resp) == "number" && typeof(output) == "number" {
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{
@@ -737,17 +767,23 @@ 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 x, ok := output.(ArObject); ok { if typeof(resp) == "number" && typeof(output) == "number" {
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{
@@ -766,7 +802,7 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
} }
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot int divide type '" + typeof(resp) + "'", "Cannot divide type '" + typeof(resp) + "'",
o.line, o.line,
o.path, o.path,
o.code, o.code,
@@ -776,142 +812,93 @@ 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
} }
var output any = resp if typeof(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 x, ok := output.(ArObject); ok {
if y, ok := x.obj["__Power__"]; ok {
val, err := runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
output = val
continue
}
}
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot power type '" + typeof(resp) + "' to type '" + typeof(output) + "'", "Cannot calculate power of type '" + typeof(resp) + "'",
o.line, o.line,
o.path, o.path,
o.code, o.code,
true, true,
} }
} }
return (output), ArErr{} output := newNumber().Set(resp.(number))
for i := 1; i < len(o.values); i++ {
resp, err := runVal(
o.values[i],
stack,
stacklevel+1,
)
resp = ArValidToAny(resp)
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 runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) { func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
@@ -931,9 +918,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 calcMul(o, stack, stacklevel+1)
case 13:
return calcMod(o, stack, stacklevel+1) return calcMod(o, stack, stacklevel+1)
case 13:
return calcMul(o, stack, stacklevel+1)
case 14: case 14:
return calcIntDiv(o, stack, stacklevel+1) return calcIntDiv(o, stack, stacklevel+1)
case 15: case 15:

49
src/platform.go Normal file
View File

@@ -0,0 +1,49 @@
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"
) )
var rand_source = rand.New(rand.NewSource(time.Now().UnixMicro())) func random() number {
return newNumber().SetFloat64(
func random() ArObject { rand.Float64(),
return Number(rand_source.Float64()) )
} }
func randomRange(args ...any) (any, ArErr) { func randomRange(args ...any) (any, ArErr) {
@@ -33,88 +33,23 @@ func randomRange(args ...any) (any, ArErr) {
EXISTS: true, EXISTS: true,
} }
} }
min := args[0].(ArObject) min := args[0].(number)
max := args[1].(ArObject) max := args[1].(number)
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: Err.Error(), message: "takes a min less than max",
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)
multiplier, err := runOperation( rand.Add(rand, min)
operationType{ return rand, ArErr{}
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 = ArObject{anymap{ var ArRandom = Map(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{
@@ -148,15 +83,22 @@ var ArRandom = ArObject{anymap{
EXISTS: true, EXISTS: true,
} }
} }
new_seed, err := numberToInt64(a[0].(ArObject)) if !a[0].(number).IsInt() {
if err != nil {
return nil, ArErr{ return nil, ArErr{
TYPE: "Runtime Error", TYPE: "Runtime Error",
message: err.Error(), message: "takes an integer not a float",
EXISTS: true, EXISTS: true,
} }
} }
rand_source.Seed(new_seed) rand.Seed(
a[0].(number).Num().Int64(),
)
return nil, ArErr{} return nil, ArErr{}
}}, }},
}} })
func initRandom() {
rand.Seed(
time.Now().UnixMicro(),
)
}

View File

@@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"math/big"
"reflect" "reflect"
) )
@@ -57,30 +56,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 compiledNumber: case number:
// if !x.sign { if !x.sign {
// return Number(compiledNumber{new(big.Rat).Neg(y)}), ArErr{} return newNumber().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
@@ -209,11 +208,7 @@ 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 compiledNumber: case bool, ArObject, number, nil, Callable, builtinFunc, anymap:
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 {
@@ -227,7 +222,6 @@ 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;5;240mBye :)\x1b[0m") fmt.Println("\x1b[0m\n\x1b[32;240mBye :)\x1b[0m")
os.Exit(0) os.Exit(0)
} }
} }
}() }()
fmt.Print("\x1b[32;5;25mWelcome to the Argon v3!\x1b[25m\n\n") fmt.Print("\x1b[32;240mWelcome to the Argon v3!\x1b[0m\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)
line, err := input("\x1b[38;5;240m" + textBefore + indentStr + " \x1b[0m\x1b[1;5;25m") inp, err := input("\x1b[38;240m" + textBefore + indentStr + " \x1b[0m")
if err != nil { if err != nil {
fmt.Println("\x1b[0m\n\x1b[32;5;25mBye :)\x1b[0m") fmt.Println("\x1b[0m\n\x1b[32;240mBye :)\x1b[0m")
os.Exit(0) os.Exit(0)
} }
code := indentStr + line code := indentStr + inp
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,16 +226,15 @@ func ArSocketServer(args ...any) (any, ArErr) {
} }
} }
networktype := ArValidToAny(args[0]).(string) networktype := ArValidToAny(args[0]).(string)
port_num := args[1].(ArObject) port := args[1].(number)
port, err := numberToInt64(port_num) if port.Denom().Int64() != 1 {
if err != nil {
return ArObject{}, ArErr{ return ArObject{}, ArErr{
TYPE: "Socket Error", TYPE: "Socket Error",
message: err.Error(), message: "Socket port must be an integer",
EXISTS: true, EXISTS: true,
} }
} }
ln, err := net.Listen(networktype, ":"+fmt.Sprint(port)) ln, err := net.Listen(networktype, ":"+fmt.Sprint(port.Num().Int64()))
if err != nil { if err != nil {
return ArObject{}, ArErr{ return ArObject{}, ArErr{
TYPE: "Socket Error", TYPE: "Socket Error",

View File

@@ -58,7 +58,9 @@ 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 x, ok := a.(ArObject); ok { if isAnyNumber(a) && isAnyNumber(b) {
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,7 +5,6 @@ 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"
) )
@@ -69,32 +68,6 @@ 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) {
@@ -151,12 +124,14 @@ func ArString(str string) ArObject {
{ {
if a[0] == nil { if a[0] == nil {
start = 0 start = 0
} else if x, ok := a[0].(ArObject); ok { } else if typeof(a[0]) != "number" || !a[0].(number).IsInt() {
start64, err := numberToInt64(x) return "", ArErr{
if err != nil { TYPE: "Type Error",
return nil, ArErr{"Type Error", err.Error(), 0, "", "", true} message: "slice index must be an integer",
EXISTS: true,
} }
start = int(start64) } else {
start = int(a[0].(number).Num().Int64())
} }
} }
if len(a) > 1 { if len(a) > 1 {
@@ -654,10 +629,10 @@ func ArString(str string) ArObject {
} }
n := a[0].(number) n := a[0].(number)
if !n.IsInt() { if !n.IsInt() {
return nil, ArErr{"ValueError", "cannot multiply string by float", 0, "", "", true} return nil, ArErr{"Value Error", "cannot multiply string by float", 0, "", "", true}
} }
if n.Sign() < 0 { if n.Sign() < 0 {
return nil, ArErr{"ValueError", "cannot multiply string by negative number", 0, "", "", true} return nil, ArErr{"Value Error", "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,11 +140,15 @@ 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) {
resp, err := input(args...) inp, err := input(args...)
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,
} }
return ArString(resp), ArErr{} }
return ArString(inp), ArErr{}
}}, }},
"pause": builtinFunc{"pause", func(args ...any) (any, ArErr) { "pause": builtinFunc{"pause", func(args ...any) (any, ArErr) {
pause() pause()

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"math"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@@ -10,7 +11,7 @@ import (
"github.com/jwalton/go-supportscolor" "github.com/jwalton/go-supportscolor"
) )
func anyToArgon(x any, representive bool, simplify bool, depth int, indent int, colored bool, plain int) string { func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored bool, plain int) string {
output := []string{} output := []string{}
maybenewline := "" maybenewline := ""
if plain == 1 { if plain == 1 {
@@ -28,9 +29,37 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
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;5;25m") output = append(output, "\x1b[35;240m")
} }
output = append(output, strconv.FormatBool(x)) output = append(output, strconv.FormatBool(x))
if colored { if colored {
@@ -38,14 +67,14 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
} }
case nil: case nil:
if colored { if colored {
output = append(output, "\x1b[31;5;25m") output = append(output, "\x1b[31;240m")
} }
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 && !representive { if callable, ok := x.obj["__string__"]; ok && !quote {
val, err := runCall( val, err := runCall(
call{ call{
Callable: callable, Callable: callable,
@@ -55,24 +84,24 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
0, 0,
) )
if !err.EXISTS { if !err.EXISTS {
output = append(output, fmt.Sprint(ArValidToAny(val))) output = append(output, anyToArgon(val, false, simplify, depth, indent, colored, plain))
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{colored}, Args: []any{},
}, },
stack{}, stack{},
0, 0,
) )
if !err.EXISTS { if !err.EXISTS {
output = append(output, fmt.Sprint(ArValidToAny(val))) output = append(output, anyToArgon(val, false, simplify, depth, indent, colored, plain))
break break
} }
} else if val, ok := x.obj["__value__"]; ok { } else if val, ok := x.obj["__value__"]; ok {
output = append(output, anyToArgon(val, representive, simplify, depth, indent, colored, plain)) output = append(output, anyToArgon(val, quote, simplify, depth, indent, colored, plain))
break break
} }
output = append(output, "<object>") output = append(output, "<object>")
@@ -99,7 +128,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
} else { } else {
outputkeyval := []string{} outputkeyval := []string{}
if colored { if colored {
outputkeyval = append(outputkeyval, "\x1b[36;5;25m") outputkeyval = append(outputkeyval, "\x1b[36;240m")
} }
outputkeyval = append(outputkeyval, key.(string)) outputkeyval = append(outputkeyval, key.(string))
if colored { if colored {
@@ -119,7 +148,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
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;5;25m(...)\x1b[0m") output = append(output, "\x1b[38;240m(...)\x1b[0m")
} else { } else {
output = append(output, "(...)") output = append(output, "(...)")
} }
@@ -144,7 +173,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
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;5;25m") output = append(output, "\x1b[38;240m")
} }
output = append(output, "<builtin function "+x.name+">") output = append(output, "<builtin function "+x.name+">")
if colored { if colored {
@@ -152,7 +181,7 @@ func anyToArgon(x any, representive bool, simplify bool, depth int, indent int,
} }
case Callable: case Callable:
if colored { if colored {
output = append(output, "\x1b[38;5;25m") output = append(output, "\x1b[38;240m")
} }
output = append(output, "<function "+x.name+">") output = append(output, "<function "+x.name+">")
if colored { if colored {

View File

@@ -103,6 +103,13 @@ 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)
} }
@@ -132,12 +139,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
return nil, worked, err, step return nil, worked, err, step
} }
} }
if !QuickKnownFailures["factorial"+code.code] && isFactorial(code) { if isNegative(code) {
resp, worked, err, i = parseFactorial(code, index, codelines) return parseNegative(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)
@@ -146,9 +149,7 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
} }
QuickKnownFailures["call"+code.code] = true QuickKnownFailures["call"+code.code] = true
} }
if isNegative(code) { if isMapGet(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_RAT, newNumber().SetInt64(2)), newNumber().SetInt64(1)}, {newNumber().Quo(PI, newNumber().SetInt64(2)), newNumber().SetInt64(1)},
{PI_RAT, newNumber()}, {PI, newNumber()},
{newNumber().Add(PI_RAT, newNumber().Quo(PI_RAT, newNumber().SetInt64(2))), newNumber().SetInt64(-1)}, {newNumber().Add(PI, newNumber().Quo(PI, 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_RAT, newNumber().SetInt64(2)) toTrim := newNumber().Mul(PI, newNumber().SetInt64(2))
toTrim.Quo(num, toTrim) toTrim.Quo(num, toTrim)
toTrim = floor(toTrim) toTrim = floor(toTrim)
toTrim.Mul(toTrim, newNumber().Mul(PI_RAT, newNumber().SetInt64(2))) toTrim.Mul(toTrim, newNumber().Mul(PI, 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_RAT) num.Quo(num, PI)
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_RAT) outputnum.Mul(outputnum, PI)
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_RAT, newNumber().SetInt64(2)))}) return builtinCall(ArSin, []any{newNumber().Add(args[0].(number), newNumber().Quo(PI, 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_RAT) outputnum.Mul(outputnum, PI)
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_RAT) num.Quo(num, PI)
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_RAT) outputnum.Mul(outputnum, PI)
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_RAT) num.Quo(num, PI)
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_RAT) outputnum.Mul(outputnum, PI)
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_RAT) num.Quo(num, PI)
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_RAT) outputnum.Mul(outputnum, PI)
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_RAT) num.Quo(num, PI)
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_RAT) outputnum.Mul(outputnum, PI)
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_RAT) num.Quo(num, PI)
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_RAT) num.Mul(num, PI)
return num, ArErr{} return num, ArErr{}
}} }}

View File

@@ -2,6 +2,8 @@ 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,13 +76,12 @@ 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{name}) contains, err := builtinCall(callable, []any{v.Name})
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -91,7 +90,7 @@ func readVariable(v accessVariable, stack stack) (any, ArErr) {
if !ok { if !ok {
continue continue
} }
return builtinCall(callable, []any{name}) return builtinCall(callable, []any{v.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}
@@ -160,7 +159,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 '=='?", code.line, code.path, code.realcode, true}, 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
} }
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
@@ -224,7 +223,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 '=='?", code.line, code.path, code.realcode, true}, 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
} }
continue continue
} }

View File

@@ -1,33 +1,45 @@
let interpret(code) = do let brainfuck(INPUT) = do
memory = map() memory = [0] * 30*1000
pointer = 0 pointer = 0
code_ptr = 0 output = ""
loops = [] i = 0
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
while (code_ptr < code.length) do term.time("brainfuck")
command = code[code_ptr] term.plain.oneLine(brainfuck(input()))
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('>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.')