fix operation translation taking ages

This commit is contained in:
2023-06-18 01:20:21 +01:00
parent 63d7616053
commit 14ae68b9d1
24 changed files with 576 additions and 441 deletions

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"files.associations": {
"*.ar": "lua"
}
}

View File

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

6
debug.bat Normal file
View File

@@ -0,0 +1,6 @@
@echo off
:: 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
go run ./src %*

2
debug_build.bat Normal file
View File

@@ -0,0 +1,2 @@
@echo off
go build -o bin/debug_argon.exe ./src

View File

@@ -1,2 +0,0 @@
forever do
term.log(random())

76
modules/welcome.ar Normal file
View File

@@ -0,0 +1,76 @@
term.log(" ____ ")
term.log(" /\\ |___ \\ ")
term.log(" / \\ _ __ __ _ ___ _ __ __ ____) |")
term.log(" / /\\ \\ | '__/ _` |/ _ \\| '_ \\ \\ \\ / /__ < ")
term.log(" / ____ \\| | | (_| | (_) | | | | \\ V /___) |")
term.log(" /_/ \\_\\_| \\__, |\\___/|_| |_| \\_/|____/ ")
term.log(" __/ | ")
term.log(" |___/ ")
term.log("----------------------------------------------")
term.log("Welcome to ARGON!")
input.pause()
term.clear()
# ARGON 3 is a math-driven programming language designed to make code easy to read and write. It's not meant to be fast, as it's interpreted. This specification should be used as a guideline, and is subject to change for later versions. Later updates for Argon 3 should be backwards compatible (where possible) with code designed for older versions of the interpreter.
term.log("ARGON 3 is a math-driven programming language")
term.log("designed to make code easy to read and write.")
term.log("It's not meant to be fast, as it's interpreted.")
term.log("This specification should be used as a guideline,")
term.log("and is subject to change for later versions.")
term.log("Later updates for Argon 3 should be backwards")
term.log("compatible (where possible) with code designed")
term.log("for older versions of the interpreter.")
term.log()
input.pause()
term.clear()
term.log("📚 Features")
term.log(" - Easy to read and write: Argon 3 is designed with clarity of code in mind, making it easier for you and others to read and write code.")
term.log(" - All numbers are stored as rational numbers, preventing precision errors.")
term.log(" - Math-driven: Designed for mathematical computations, Argon 3 uses techniques and rules set in maths. It's designed to be easy for mathematicians to write and understand algorithms in.")
term.log(" - Interpreted: Argon 3 is an interpreted language, so you don't need to compile your code before running it.")
term.log(" - Cross-platform: Argon 3 can be run on any platform that has an interpreter for it.")
term.log(" - Lightweight: The Argon 3 interpreter is small and doesn't require a lot of system resources to run.")
term.log()
input.pause()
term.clear()
term.log("🚀 Example Code")
term.log()
term.log("Here's an example of how to define a function in Argon 3:")
term.log()
term.log("f(x) = x^2 + 2*x + 1")
term.log("term.log('f(10) =', f(10))")
term.log("\n")
input.pause()
term.clear()
# license: MIT
term.log("📜 License")
term.log()
term.log("MIT License\n\nCopyright (c) 2022 Open Argon")
term.log()
term.log("Permission is hereby granted, free of charge, to any person obtaining a copy")
term.log("of this software and associated documentation files (the \"Software\"), to deal")
term.log("in the Software without restriction, including without limitation the rights")
term.log("to use, copy, modify, merge, publish, distribute, sublicense, and/or sell")
term.log("copies of the Software, and to permit persons to whom the Software is")
term.log("furnished to do so, subject to the following conditions:")
term.log("The above copyright notice and this permission notice shall be included in all")
term.log("copies or substantial portions of the Software.")
term.log()
term.log("THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR")
term.log("IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,")
term.log("FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE")
term.log("AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER")
term.log("LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,")
term.log("OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE")
term.log("SOFTWARE.")
term.log()
term.log("remember this is subject to change and this version is not guaranteed to be up to date,\nalways check the latest version of the license agreement at https://raw.githubusercontent.com/Open-Argon/argon-v3/master/licence")
term.log()
input.pause()
term.clear()

View File

@@ -551,7 +551,8 @@ func ArArray(arr []any) ArObject {
for i, v := range arr { for i, v := range arr {
res, err := runOperation(operationType{ res, err := runOperation(operationType{
operation: 8, operation: 8,
values: []any{v, args[0].(ArObject).obj["__value__"].([]any)[i]}, value1: v,
value2: args[0].(ArObject).obj["__value__"].([]any)[i],
}, stack{}, 0) }, stack{}, 0)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
@@ -575,7 +576,8 @@ func ArArray(arr []any) ArObject {
for _, v := range arr { for _, v := range arr {
res, err := runOperation(operationType{ res, err := runOperation(operationType{
operation: 8, operation: 8,
values: []any{v, args[0]}, value1: v,
value2: args[0],
}, stack{}, 0) }, stack{}, 0)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err

View File

@@ -13,10 +13,7 @@ func anyToBool(x any) bool {
case nil: case nil:
return false return false
case ArObject: case ArObject:
if typeof(x) == "array" { return anyToBool(ArValidToAny(x))
return len(x.obj["__value__"].([]any)) != 0
}
return len(x.obj) != 0
case builtinFunc: case builtinFunc:
return true return true
case Callable: case Callable:

View File

@@ -3,19 +3,41 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"sync"
) )
var debug = os.Getenv("__ARGON_DEBUG__") == "true" var debug = os.Getenv("__ARGON_DEBUG__") == "true"
func debugPrintln(a ...any) { var __debugPrints = [][]any{}
var __debugPrintsLock = sync.RWMutex{}
func debugInit() {
if debug { if debug {
fmt.Println("In debug mode...")
go func() { go func() {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
fmt.Println("debugPrintln: panic:", r) fmt.Println("debugPrintln: panic:", r)
} }
}() }()
fmt.Println(a...) for {
__debugPrintsLock.RLock()
for _, v := range __debugPrints {
fmt.Println(v...)
}
__debugPrintsLock.RUnlock()
__debugPrintsLock.Lock()
__debugPrints = [][]any{}
__debugPrintsLock.Unlock()
}
}() }()
} }
} }
func debugPrintln(a ...any) {
if debug {
__debugPrintsLock.Lock()
__debugPrints = append(__debugPrints, a)
__debugPrintsLock.Unlock()
}
}

View File

@@ -58,3 +58,9 @@ func getPassword(args ...any) (string, error) {
fmt.Print("\r") fmt.Print("\r")
return string(password), nil return string(password), nil
} }
func pause() {
fmt.Print("Press any key to continue...")
term.ReadPassword(int(os.Stdin.Fd()))
fmt.Println()
}

View File

@@ -15,7 +15,7 @@ func newscope() ArObject {
} }
func main() { func main() {
debugPrintln("In debug mode...") debugInit()
if !debug { if !debug {
defer func() { defer func() {

View File

@@ -196,7 +196,8 @@ func Map(m anymap) ArObject {
} }
val, err := runOperation(operationType{ val, err := runOperation(operationType{
operation: 9, operation: 9,
values: []any{v, a[k]}, value1: v,
value2: a[k],
}, stack{}, 0) }, stack{}, 0)
if err.EXISTS { if err.EXISTS {
return val, err return val, err

View File

@@ -15,13 +15,20 @@ func isNegative(code UNPARSEcode) bool {
return negativeCompile.MatchString(code.code) return negativeCompile.MatchString(code.code)
} }
func parseNegative(code UNPARSEcode, index int, codeline []UNPARSEcode) (negative, bool, ArErr, int) { func parseNegative(code UNPARSEcode, index int, codeline []UNPARSEcode) (any, bool, ArErr, int) {
trimmed := strings.TrimSpace(code.code)
trimmednegative := strings.TrimLeft(trimmed, "-")
difference := len(trimmed) - len(trimmednegative)
resp, worked, err, i := translateVal(UNPARSEcode{ resp, worked, err, i := translateVal(UNPARSEcode{
code: strings.TrimSpace(code.code)[1:], code: trimmednegative,
realcode: code.realcode, realcode: code.realcode,
line: code.line, line: code.line,
path: code.path, path: code.path,
}, index, codeline, 0) }, index, codeline, 0)
if difference%2 == 0 {
return resp, worked, err, i
}
return negative{ return negative{
VAL: resp, VAL: resp,
line: code.line, line: code.line,

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"math" "math"
"reflect" "reflect"
"strings"
) )
var operations = [][]string{ var operations = [][]string{
@@ -50,7 +51,8 @@ var one = newNumber().SetInt64(1)
type operationType struct { type operationType struct {
operation int operation int
values []any value1 any
value2 any
line int line int
code string code string
path string path string
@@ -58,67 +60,60 @@ type operationType struct {
func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (operationType, bool, ArErr, int) { func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (operationType, bool, ArErr, int) {
for i := 0; i < len(operations); i++ { for i := 0; i < len(operations); i++ {
values := []any{} for j := 0; j < len(operations[i]); j++ {
current := 0 split := strings.Split(code.code, operations[i][j])
totalindex := 1 if len(split) <= 1 {
for l := 0; l < len(code.code); l++ { continue
for j := 0; j < len(operations[i]); j++ {
if len(code.code[l:]) >= len(operations[i][j]) && code.code[l:l+len(operations[i][j])] == operations[i][j] {
resp, success, _, respindex := translateVal(
UNPARSEcode{
code: code.code[current:l],
realcode: code.realcode,
line: code.line,
path: code.path,
}, index, codelines, 0)
if success {
totalindex += respindex - 1
values = append(values, resp)
current = l + len(operations[i][j])
}
}
} }
} for k := 0; k < len(split)-1; k++ {
if len(values) > 0 { if len(strings.TrimSpace(split[k])) == 0 || len(strings.TrimSpace(split[k+1])) == 0 {
resp, success, err, respindex := translateVal( break
UNPARSEcode{ }
code: code.code[current:], val1, worked, err, step1 := translateVal(UNPARSEcode{
code: strings.Join(split[:k+1], operations[i][j]),
realcode: code.realcode, realcode: code.realcode,
line: code.line, line: code.line,
path: code.path, path: code.path,
}, index, codelines, 0) }, index, codelines, 0)
if success { if !worked || err.EXISTS {
totalindex += respindex - 1 if k == len(split)-1 {
values = append(values, resp) return operationType{}, false, err, 0
} else {
continue
}
}
val2, worked, err, step2 := translateVal(UNPARSEcode{
code: strings.Join(split[k+1:], operations[i][j]),
realcode: code.realcode,
line: code.line,
path: code.path,
}, index, codelines, 0)
if !worked || err.EXISTS {
if k == len(split)-1 {
return operationType{}, false, err, 0
} else {
continue
}
}
return operationType{ return operationType{
i, i,
values, val1,
val2,
code.line, code.line,
code.realcode, code.code,
code.path, code.path,
}, true, err, totalindex }, true, ArErr{}, step1 + step2 - 1
} }
return operationType{}, false, err, totalindex
} }
} }
return operationType{}, false, ArErr{}, 0 return operationType{}, false, ArErr{}, 0
} }
func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) { func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
if len(o.values) != 2 {
return false, ArErr{
"Runtime Error",
"Invalid number of values for comparison",
o.line,
o.path,
o.code,
true,
}
}
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -127,7 +122,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
} }
resp2, err := runVal( resp2, err := runVal(
o.values[1], o.value2,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -261,7 +256,7 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -272,52 +267,46 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
if isAnyNumber(resp) { if isAnyNumber(resp) {
output = newNumber().Set(resp.(number)) output = newNumber().Set(resp.(number))
} }
for i := 1; i < len(o.values); i++ { resp, err = runVal(
resp, err := runVal( o.value2,
o.values[i], stack,
stack, stacklevel+1,
stacklevel+1, )
) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} if typeof(output) == "number" && typeof(resp) == "number" {
if typeof(output) == "number" && typeof(resp) == "number" { return output.(number).Sub(output.(number), resp.(number)), ArErr{}
output = output.(number).Sub(output.(number), resp.(number)) } else if x, ok := output.(ArObject); ok {
continue if y, ok := x.obj["__Subtract__"]; ok {
} else if x, ok := output.(ArObject); ok { val, err := runCall(
if y, ok := x.obj["__Subtract__"]; ok { call{
val, err := runCall( y,
call{ []any{resp},
y, o.code,
[]any{resp}, o.line,
o.code, o.path,
o.line, }, stack, stacklevel+1)
o.path, if err.EXISTS {
}, stack, stacklevel+1) return nil, err
if err.EXISTS { }
return nil, err return val, ArErr{}
} }
output = val }
continue return nil, ArErr{
} "Runtime Error",
} "Cannot subtract type '" + typeof(resp) + "' from type '" + typeof(output) + "'",
return nil, ArErr{ o.line,
"Runtime Error", o.path,
"Cannot subtract type '" + typeof(resp) + "' from type '" + typeof(output) + "'", o.code,
o.line, true,
o.path,
o.code,
true,
}
} }
return output, ArErr{}
} }
func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -328,52 +317,49 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
if isAnyNumber(resp) { if isAnyNumber(resp) {
output = newNumber().Set(resp.(number)) output = newNumber().Set(resp.(number))
} }
for i := 1; i < len(o.values); i++ { resp, err = runVal(
resp, err := runVal( o.value2,
o.values[i], stack,
stack, stacklevel+1,
stacklevel+1, )
) resp = ArValidToAny(resp)
resp = ArValidToAny(resp) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} if typeof(resp) == "number" && typeof(output) == "number" {
if typeof(resp) == "number" && typeof(output) == "number" { output = output.(number).Quo(output.(number), resp.(number))
output = output.(number).Quo(output.(number), resp.(number)) return output, ArErr{}
continue } else if x, ok := output.(ArObject); ok {
} 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{ y,
y, []any{resp},
[]any{resp}, o.code,
o.code, o.line,
o.line, o.path,
o.path, }, stack, stacklevel+1)
}, stack, stacklevel+1) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err
}
output = val
continue
} }
} output = val
return nil, ArErr{ return output, ArErr{}
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
} }
} }
return output, ArErr{} return nil, ArErr{
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
} }
func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -384,51 +370,64 @@ func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {
if typeof(output) == "number" { if typeof(output) == "number" {
output = newNumber().Set(output.(number)) output = newNumber().Set(output.(number))
} }
for i := 1; i < len(o.values); i++ { resp, err = runVal(
resp, err := runVal( o.value2,
o.values[i], stack,
stack, stacklevel+1,
stacklevel+1, )
) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} if typeof(output) == "number" && typeof(resp) == "number" {
if typeof(output) == "number" && typeof(resp) == "number" { output = output.(number).Add(output.(number), resp.(number))
output = output.(number).Add(output.(number), resp.(number)) return output, ArErr{}
continue } else if x, ok := output.(ArObject); ok {
} 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{ y,
y, []any{resp},
[]any{resp}, o.code,
o.code, 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 return output, ArErr{}
} }
} }
return nil, ArErr{ }
"Runtime Error", if x, ok := resp.(ArObject); ok {
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'", if y, ok := x.obj["__PostAdd__"]; ok {
o.line, val, err := runCall(
o.path, call{
o.code, y,
true, []any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if !err.EXISTS {
output = val
return output, ArErr{}
}
} }
} }
return (output), ArErr{}
return nil, ArErr{
"Runtime Error",
"Cannot add type '" + typeof(resp) + "' to type '" + typeof(output) + "'",
o.line,
o.path,
o.code,
true,
}
} }
func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -439,88 +438,100 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
if isAnyNumber(resp) { if isAnyNumber(resp) {
output = newNumber().Set(resp.(number)) output = newNumber().Set(resp.(number))
} }
for i := 1; i < len(o.values); i++ { resp, err = runVal(
resp, err := runVal( o.value2,
o.values[i], stack,
stack, stacklevel+1,
stacklevel+1, )
) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} if typeof(output) == "number" && typeof(resp) == "number" {
if typeof(output) == "number" && typeof(resp) == "number" { output = output.(number).Mul(output.(number), resp.(number))
output = output.(number).Mul(output.(number), resp.(number)) return output, ArErr{}
continue } else if x, ok := output.(ArObject); ok {
} 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{ y,
y, []any{resp},
[]any{resp}, o.code,
o.code, o.line,
o.line, o.path,
o.path, }, stack, stacklevel+1)
}, stack, stacklevel+1) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} output = val
output = val return output, ArErr{}
continue }
} }
} return nil, ArErr{
return nil, ArErr{ "Runtime Error",
"Runtime Error", "Cannot multiply type '" + typeof(resp) + "'",
"Cannot multiply type '" + typeof(resp) + "'", o.line,
o.line, o.path,
o.path, o.code,
o.code, true,
true,
}
} }
return output, ArErr{}
} }
func calcAnd(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcAnd(o operationType, stack stack, stacklevel int) (any, ArErr) {
var output any = false resp, err := runVal(
for i := 0; i < len(o.values); i++ { o.value1,
resp, err := runVal( stack,
o.values[i], stacklevel+1,
stack, )
stacklevel+1, if err.EXISTS {
) return nil, err
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
if !anyToBool(resp) {
return resp, ArErr{}
}
output = resp
} }
return output, ArErr{} if !anyToBool(resp) {
return resp, ArErr{}
}
resp, err = runVal(
o.value2,
stack,
stacklevel+1,
)
if err.EXISTS {
return nil, err
}
if !anyToBool(resp) {
return resp, ArErr{}
}
return resp, ArErr{}
} }
func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
var output any = false resp, err := runVal(
for i := 0; i < len(o.values); i++ { o.value1,
resp, err := runVal( stack,
o.values[i], stacklevel+1,
stack, )
stacklevel+1, resp = ArValidToAny(resp)
) if err.EXISTS {
resp = ArValidToAny(resp) return nil, err
if err.EXISTS {
return nil, err
}
if anyToBool(resp) {
return resp, ArErr{}
}
output = resp
} }
return output, ArErr{} if anyToBool(resp) {
return resp, ArErr{}
}
resp, err = runVal(
o.value1,
stack,
stacklevel+1,
)
resp = ArValidToAny(resp)
if err.EXISTS {
return nil, err
}
if anyToBool(resp) {
return resp, ArErr{}
}
return resp, ArErr{}
} }
// InSlice checks if an element is present in a slice of any type.
// It returns true if the element is found, false otherwise.
func InSlice(a any, list []any) bool { func InSlice(a any, list []any) bool {
for _, b := range list { for _, b := range list {
if b == a { if b == a {
@@ -529,41 +540,35 @@ func InSlice(a any, list []any) bool {
} }
return false return false
} }
// calcNotIn is a function that calculates the 'not in' operation between two values.
// It takes in an operationType 'o', a stack 'stack', and a stack level 'stacklevel'.
// It returns an 'any' value and an 'ArErr' error.
// The 'o' parameter contains information about the operation to be performed, including the values to be compared, the line of code, and the file path.
func calcNotIn(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcNotIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
if len(o.values) != 2 {
return false, ArErr{
"Runtime Error",
"Invalid number of arguments for 'not in'",
o.line,
o.path,
o.code,
true,
}
}
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
resp2, err := runVal( resp2, err := runVal(
o.values[1], o.value2,
stack, stack,
stacklevel+1, stacklevel+1,
) )
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
if x, ok := resp.(ArObject); ok { if x, ok := resp2.(ArObject); ok {
if y, ok := x.obj["__NotContains__"]; ok { if y, ok := x.obj["__NotContains__"]; ok {
return runCall( return runCall(
call{ call{
y, y,
[]any{resp2}, []any{resp},
o.code, o.code,
o.line, o.line,
o.path, o.path,
@@ -580,19 +585,13 @@ func calcNotIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
} }
} }
// calcIn is a function that calculates the 'in' operation between two values.
// It takes in an operationType 'o', a stack 'stack', and a stack level 'stacklevel'.
// It returns an 'any' value and an 'ArErr' error.
// The 'o' parameter contains information about the operation to be performed, including the values to be compared, the line of code, and the file path.
func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
if len(o.values) != 2 {
return false, ArErr{
"Runtime Error",
"Invalid number of arguments for 'not in'",
o.line,
o.path,
o.code,
true,
}
}
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -601,7 +600,7 @@ func calcIn(o operationType, stack stack, stacklevel int) (any, ArErr) {
} }
resp2, err := runVal( resp2, err := runVal(
o.values[1], o.value2,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -676,7 +675,7 @@ func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, A
func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -687,55 +686,52 @@ func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
if isAnyNumber(resp) { if isAnyNumber(resp) {
output = newNumber().Set(resp.(number)) output = newNumber().Set(resp.(number))
} }
for i := 1; i < len(o.values); i++ { resp, err = runVal(
resp, err := runVal( o.value2,
o.values[i], stack,
stack, stacklevel+1,
stacklevel+1, )
) resp = ArValidToAny(resp)
resp = ArValidToAny(resp) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} if typeof(resp) == "number" && typeof(output) == "number" {
if typeof(resp) == "number" && typeof(output) == "number" { x := newNumber().Set(resp.(number))
x := newNumber().Set(resp.(number)) x.Quo(output.(number), x)
x.Quo(output.(number), x) x = floor(x)
x = floor(x) x.Mul(x, resp.(number))
x.Mul(x, resp.(number)) output.(number).Sub(output.(number), x)
output.(number).Sub(output.(number), x) return output, ArErr{}
continue } else if x, ok := output.(ArObject); ok {
} 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{ y,
y, []any{resp},
[]any{resp}, o.code,
o.code, o.line,
o.line, o.path,
o.path, }, stack, stacklevel+1)
}, stack, stacklevel+1) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err
}
output = val
continue
} }
} output = val
return nil, ArErr{ return output, ArErr{}
"Runtime Error",
"Cannot calculate modulus of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
} }
} }
return output, ArErr{} return nil, ArErr{
"Runtime Error",
"Cannot calculate modulus of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
} }
func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -746,51 +742,48 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
if isAnyNumber(resp) { if isAnyNumber(resp) {
output = newNumber().Set(resp.(number)) output = newNumber().Set(resp.(number))
} }
for i := 1; i < len(o.values); i++ { resp, err = runVal(
resp, err := runVal( o.value2,
o.values[i], stack,
stack, stacklevel+1,
stacklevel+1, )
) resp = ArValidToAny(resp)
resp = ArValidToAny(resp) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} if typeof(resp) == "number" && typeof(output) == "number" {
if typeof(resp) == "number" && typeof(output) == "number" { output = output.(number).Quo(output.(number), resp.(number))
output = output.(number).Quo(output.(number), resp.(number)) return output, ArErr{}
continue } else if x, ok := output.(ArObject); ok {
} 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{ y,
y, []any{resp},
[]any{resp}, o.code,
o.code, o.line,
o.line, o.path,
o.path, }, stack, stacklevel+1)
}, stack, stacklevel+1) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err
}
output = val
continue
} }
} output = val
return nil, ArErr{ return output, ArErr{}
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
} }
} }
return output, ArErr{} return nil, ArErr{
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
} }
func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) { func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
resp, err := runVal( resp, err := runVal(
o.values[0], o.value1,
stack, stack,
stacklevel+1, stacklevel+1,
) )
@@ -809,69 +802,67 @@ func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
} }
} }
output := newNumber().Set(resp.(number)) output := newNumber().Set(resp.(number))
for i := 1; i < len(o.values); i++ { resp, err = runVal(
resp, err := runVal( o.value2,
o.values[i], stack,
stack, stacklevel+1,
stacklevel+1, )
) resp = ArValidToAny(resp)
resp = ArValidToAny(resp) if err.EXISTS {
if err.EXISTS { return nil, err
return nil, err }
} if typeof(resp) == "number" {
if typeof(resp) == "number" { n := newNumber().Set(resp.(number))
n := newNumber().Set(resp.(number)) if n.Cmp(newNumber().SetInt64(10)) <= 0 {
if n.Cmp(newNumber().SetInt64(10)) <= 0 { toOut := newNumber().SetInt64(1)
toOut := newNumber().SetInt64(1) clone := newNumber().Set(output)
clone := newNumber().Set(output) nAbs := (abs(newNumber().Set(n)))
nAbs := (abs(newNumber().Set(n))) j := newNumber()
j := newNumber() for ; j.Cmp(nAbs) < 0; j.Add(j, one) {
for ; j.Cmp(nAbs) < 0; j.Add(j, one) { toOut.Mul(toOut, clone)
toOut.Mul(toOut, clone) }
}
nAbs.Sub(nAbs, j) nAbs.Sub(nAbs, j)
if nAbs.Cmp(newNumber()) < 0 { if nAbs.Cmp(newNumber()) < 0 {
j.Sub(j, one) j.Sub(j, one)
n1, _ := toOut.Float64() n1, _ := toOut.Float64()
n2, _ := nAbs.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)) calculated := newNumber().SetFloat64(math.Pow(n1, n2))
if calculated == nil { if calculated == nil {
calculated = infinity calculated = infinity
} }
output.Mul(output, calculated) 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() n1, _ := output.Float64()
n2, _ := resp.(number).Float64() n2, _ := resp.(number).Float64()
output = newNumber().SetFloat64(math.Pow(n1, n2)) output = newNumber().SetFloat64(math.Pow(n1, n2))
if output == nil { if output == nil {
output = infinity output = infinity
}
*/
} else {
return nil, ArErr{
"Runtime Error",
"Cannot calculate power of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
} }
*/
} else {
return nil, ArErr{
"Runtime Error",
"Cannot calculate power of type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
} }
} }
return output, ArErr{} return output, ArErr{}

View File

@@ -567,6 +567,18 @@ func ArString(str string) ArObject {
} }
return strings.Join([]string{str, a[0].(string)}, ""), ArErr{} return strings.Join([]string{str, a[0].(string)}, ""), ArErr{}
}} }}
obj.obj["__PostAdd__"] = builtinFunc{
"__PostAdd__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"TypeError", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
a[0] = ArValidToAny(a[0])
if typeof(a[0]) != "string" {
a[0] = anyToArgon(a[0], false, false, 3, 0, false, 0)
}
return strings.Join([]string{a[0].(string), str}, ""), ArErr{}
}}
obj.obj["__Multiply__"] = builtinFunc{ obj.obj["__Multiply__"] = builtinFunc{
"__Multiply__", "__Multiply__",
func(a ...any) (any, ArErr) { func(a ...any) (any, ArErr) {

View File

@@ -131,11 +131,12 @@ var ArInput = Map(
} }
return ArString(resp), ArErr{} return ArString(resp), ArErr{}
}}, }},
"__call__": builtinFunc{"input", func(args ...any) (any, ArErr) {
return input(args...), ArErr{}
}},
"pause": builtinFunc{"pause", func(args ...any) (any, ArErr) {
pause()
return nil, ArErr{}
}},
}, },
) )
func init() {
ArInput.obj["__call__"] = builtinFunc{"input", func(args ...any) (any, ArErr) {
return input(args...), ArErr{}
}}
}

View File

@@ -151,6 +151,7 @@ func translate(codelines []UNPARSEcode) ([]any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
translated = append(translated, val) translated = append(translated, val)
} }
return translated, ArErr{} return translated, ArErr{}

View File

@@ -1 +0,0 @@
term.log(null)

21
testingoop.py Normal file
View File

@@ -0,0 +1,21 @@
class obj1:
def __init__(self) -> None:
pass
def __add__(self, other):
print("obj1")
return 10
class obj2:
def __init__(self) -> None:
pass
def __add__(self, other):
print("obj2")
return 20
obj1 = obj1()
obj2 = obj2()
print(obj1 + obj2)
print(obj2 + obj1)

View File

@@ -15,7 +15,7 @@ let interpret(code) = do
else if (command == '-') do else if (command == '-') do
if (pointer not in memory) memory[pointer] = 0 if (pointer not in memory) memory[pointer] = 0
memory[pointer] = memory[pointer] - 1 memory[pointer] = memory[pointer] - 1
else if (command == '.') term.plain.oneLine(chr(memory.get(pointer, 0)), end='') else if (command == '.') term.log((memory.get(pointer, 0)))
else if (command == ',') memory[pointer] = ord(input()) else if (command == ',') memory[pointer] = ord(input())
else if (command == '[') do else if (command == '[') do
if (memory.get(pointer, 0) == 0) do if (memory.get(pointer, 0) == 0) do
@@ -30,5 +30,5 @@ let interpret(code) = do
else loops.pop() else loops.pop()
code_ptr = code_ptr + 1 code_ptr = code_ptr + 1
term.log("hello worldf")
interpret('>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<++.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-]<+.') interpret('>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.')

View File

@@ -2,4 +2,4 @@ import "csv" as csv
let table = (csv.read("tests/test.csv")) let table = (csv.read("tests/test.csv"))
term.log(number(table[::-1][0][::-1][0])) term.log(table)

View File

@@ -1,19 +1,15 @@
let zero = 1/infinity let zero = 1e-1000
let diff(f) = (x) = (f(x + zero) - f(x)) / zero let diff(f) = (x) = (f(x + zero) - f(x)) / zero
let count = 0
let f(x) = do let f(x) = do
count = count + 1
term.log(count)
return x^10+x^9+x^8+x^7+x^6+x^5+x^4+x^3+x^2+x+1 return x^10+x^9+x^8+x^7+x^6+x^5+x^4+x^3+x^2+x+1
x = 100 let x = 100
d = 0 let d = 0
forever do forever do
n = f(x) let n = f(x)
term.log("f"+("'"*d)+"("+x+") = "+n) term.log("f"+("'"*d)+"("+x+") = "+n)
if (n == 0) break if (n == 0) break
f = diff(f) f = diff(f)
d = d + 1 d = d + 1
count = 0

View File

@@ -1,7 +1,8 @@
f() = do f() = do
a = [] let a = []
for (i from 0 to 100000) a.append(i) for (i from 0 to 10000000) a.append(i)
term.log("start") term.log("start")
f() f()
term.log("end") term.log("end")
input()

View File

@@ -1,9 +0,0 @@
term.log(" /\\ |___ \\ ")
term.log(" / \\ _ __ __ _ ___ _ __ __ ____) |")
term.log(" / /\\ \\ | '__/ _` |/ _ \\| '_ \\ \\ \\ / /__ < ")
term.log(" / ____ \\| | | (_| | (_) | | | | \\ V /___) |")
term.log(" /_/ \\_\\_| \\__, |\\___/|_| |_| \\_/|____/ ")
term.log(" __/ | ")
term.log(" |___/ ")
term.log("----------------------------------------------")
term.log("Welcome to ARGON!")