mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 00:46:07 +00:00
add create functions
This commit is contained in:
23
package.json
23
package.json
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "argon-v3",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "The go to language for mathematicians!",
|
|
||||||
"scripts": {
|
|
||||||
"build": "mkdir -p build && go build -o build/argon ./src",
|
|
||||||
"dev": "nodemon -x go run ./src/. --signal SIGKILL -e go --verbose",
|
|
||||||
"start": "go run ./src/."
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/Ugric/argon-v3.git"
|
|
||||||
},
|
|
||||||
"author": "",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/Ugric/argon-v3/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/Ugric/argon-v3#readme",
|
|
||||||
"dependencies": {
|
|
||||||
"nodemon": "^2.0.20"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,7 @@ ARGON 3 is a math-driven programming language designed to make code easy to read
|
|||||||
- Lightweight: The Argon 3 interpreter is small and doesn't require a lot of system resources to run.
|
- Lightweight: The Argon 3 interpreter is small and doesn't require a lot of system resources to run.
|
||||||
|
|
||||||
## 💻 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-v3(.exe)`.
|
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)`.
|
||||||
|
|
||||||
## 📖 Usage
|
## 📖 Usage
|
||||||
|
|
||||||
|
|||||||
31
src/brackets.go
Normal file
31
src/brackets.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
var bracketsCompile = makeRegex(`( *)\((.|\n)+\)( *)`)
|
||||||
|
|
||||||
|
type brackets struct {
|
||||||
|
VAL any
|
||||||
|
line int
|
||||||
|
code string
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBrackets(code UNPARSEcode) bool {
|
||||||
|
return bracketsCompile.MatchString(code.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseBrackets(code UNPARSEcode, index int, codeline []UNPARSEcode) (brackets, bool, ArErr, int) {
|
||||||
|
resp, worked, err, i := translateVal(UNPARSEcode{
|
||||||
|
code: strings.TrimSpace(code.code)[1 : len(code.code)-1],
|
||||||
|
realcode: code.realcode,
|
||||||
|
line: code.line,
|
||||||
|
path: code.path,
|
||||||
|
}, index, codeline, false)
|
||||||
|
return brackets{
|
||||||
|
VAL: resp,
|
||||||
|
line: code.line,
|
||||||
|
code: code.realcode,
|
||||||
|
path: code.path,
|
||||||
|
}, worked, err, i
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
type builtinFunc struct {
|
type builtinFunc struct {
|
||||||
@@ -25,9 +25,17 @@ func ArgonAdd(args ...any) (any, ArErr) {
|
|||||||
}, args), ArErr{}
|
}, args), ArErr{}
|
||||||
}
|
}
|
||||||
func ArgonDiv(args ...any) (any, ArErr) {
|
func ArgonDiv(args ...any) (any, ArErr) {
|
||||||
return reduce(func(x any, y any) any {
|
if len(args) == 0 {
|
||||||
return newNumber().Quo(y.(number), x.(number))
|
return nil, ArErr{TYPE: "Division Error", message: "Cannot divide nothing", EXISTS: true}
|
||||||
}, args), ArErr{}
|
}
|
||||||
|
output := args[0].(number)
|
||||||
|
for i := 1; i < len(args); i++ {
|
||||||
|
if args[i].(number).Cmp(newNumber()) == 0 {
|
||||||
|
return nil, ArErr{TYPE: "Division Error", message: "Cannot divide by zero", EXISTS: true}
|
||||||
|
}
|
||||||
|
output = newNumber().Quo(output, args[i].(number))
|
||||||
|
}
|
||||||
|
return output, ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArgonMult(args ...any) (any, ArErr) {
|
func ArgonMult(args ...any) (any, ArErr) {
|
||||||
@@ -36,14 +44,61 @@ func ArgonMult(args ...any) (any, ArErr) {
|
|||||||
}, args), ArErr{}
|
}, args), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArgonSleep(args ...any) (any, ArErr) {
|
func ArgonInput(args ...any) (any, ArErr) {
|
||||||
|
// allow a message to be passed in as an argument
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
float, _ := args[0].(number).Float64()
|
fmt.Print(anyToArgon(args[0], false))
|
||||||
time.Sleep(time.Duration(float*1000000000) * time.Nanosecond)
|
|
||||||
}
|
}
|
||||||
return nil, ArErr{}
|
var input string
|
||||||
|
fmt.Scanln(&input)
|
||||||
|
return input, ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArgonTimestamp(args ...any) (any, ArErr) {
|
func ArgonNumber(args ...any) (any, ArErr) {
|
||||||
return newNumber().Quo(newNumber().SetInt64(time.Now().UnixNano()), newNumber().SetInt64(1000000000)), ArErr{}
|
if len(args) == 0 {
|
||||||
|
return newNumber(), ArErr{}
|
||||||
|
}
|
||||||
|
switch x := args[0].(type) {
|
||||||
|
case string:
|
||||||
|
if !numberCompile.MatchString(x) {
|
||||||
|
return nil, ArErr{TYPE: "Number Error", message: "Cannot convert type '" + typeof(x) + "' to a number", EXISTS: true}
|
||||||
|
}
|
||||||
|
N, _ := newNumber().SetString(x)
|
||||||
|
return N, ArErr{}
|
||||||
|
case number:
|
||||||
|
return x, ArErr{}
|
||||||
|
case bool:
|
||||||
|
if x {
|
||||||
|
return newNumber().SetInt64(1), ArErr{}
|
||||||
|
}
|
||||||
|
return newNumber().SetInt64(0), ArErr{}
|
||||||
|
case nil:
|
||||||
|
return newNumber(), ArErr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, ArErr{TYPE: "Number Error", message: "Cannot convert " + typeof(args[0]) + " to a number", EXISTS: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArgonSqrt(a ...any) (any, ArErr) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return nil, ArErr{TYPE: "sqrt", message: "sqrt takes 1 argument",
|
||||||
|
EXISTS: true}
|
||||||
|
}
|
||||||
|
r := a[0].(number)
|
||||||
|
|
||||||
|
if r.Sign() < 0 {
|
||||||
|
return nil, ArErr{TYPE: "sqrt", message: "sqrt takes a positive number",
|
||||||
|
EXISTS: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
var x big.Float
|
||||||
|
x.SetPrec(30) // I didn't figure out the 'Prec' part correctly, read the docs more carefully than I did and experiement
|
||||||
|
x.SetRat(r)
|
||||||
|
|
||||||
|
var s big.Float
|
||||||
|
s.SetPrec(15)
|
||||||
|
s.Sqrt(&x)
|
||||||
|
|
||||||
|
r, _ = s.Rat(nil)
|
||||||
|
return r, ArErr{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,32 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
var vars = map[string]variableValue{}
|
var vars = map[string]any{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
vars["log"] = variableValue{
|
vars["log"] = builtinFunc{"log", ArgonLog}
|
||||||
EXISTS: true,
|
vars["add"] = builtinFunc{"add", ArgonAdd}
|
||||||
VAL: builtinFunc{"log", ArgonLog},
|
vars["div"] = builtinFunc{"div", ArgonDiv}
|
||||||
}
|
vars["true"] = true
|
||||||
vars["add"] = variableValue{
|
vars["false"] = false
|
||||||
EXISTS: true,
|
vars["null"] = nil
|
||||||
VAL: builtinFunc{"add", ArgonAdd},
|
vars["input"] = builtinFunc{"input", ArgonInput}
|
||||||
}
|
vars["number"] = builtinFunc{"number", ArgonNumber}
|
||||||
vars["div"] = variableValue{
|
vars["mult"] = builtinFunc{"mult", ArgonMult}
|
||||||
EXISTS: true,
|
vars["length"] = builtinFunc{"length", func(a ...any) (any, ArErr) {
|
||||||
VAL: builtinFunc{"div", ArgonDiv},
|
switch x := a[0].(type) {
|
||||||
}
|
case string:
|
||||||
vars["true"] = variableValue{
|
return len(x), ArErr{}
|
||||||
EXISTS: true,
|
case ArMap:
|
||||||
VAL: true,
|
return len(x), ArErr{}
|
||||||
}
|
}
|
||||||
vars["false"] = variableValue{
|
return nil, ArErr{TYPE: "TypeError", message: "Cannot get length of " + typeof(a[0]), EXISTS: true}
|
||||||
EXISTS: true,
|
}}
|
||||||
VAL: false,
|
vars["time"] = ArTime
|
||||||
}
|
|
||||||
vars["mult"] = variableValue{
|
|
||||||
EXISTS: true,
|
|
||||||
VAL: builtinFunc{"mult", ArgonMult},
|
|
||||||
}
|
|
||||||
vars["time"] = variableValue{
|
|
||||||
EXISTS: true,
|
|
||||||
VAL: ArMap{"snooze": builtinFunc{"snooze", ArgonSleep}, "now": builtinFunc{"now", ArgonTimestamp}},
|
|
||||||
}
|
|
||||||
pi, _ := newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
|
pi, _ := newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
|
||||||
vars["PI"] = variableValue{
|
vars["PI"] = pi
|
||||||
EXISTS: true,
|
vars["π"] = pi
|
||||||
VAL: pi,
|
e, _ := newNumber().SetString("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354")
|
||||||
}
|
vars["e"] = e
|
||||||
|
vars["sqrt"] = builtinFunc{"sqrt", ArgonSqrt}
|
||||||
|
vars["√"] = builtinFunc{"sqrt", ArgonSqrt}
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/call.go
21
src/call.go
@@ -1,10 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var callCompile = makeRegex("( *).+\\(.*\\)( *)")
|
var callCompile = makeRegex("( *)(.|\n)+\\((.|\n)*\\)( *)")
|
||||||
|
|
||||||
type call struct {
|
type call struct {
|
||||||
callable any
|
callable any
|
||||||
@@ -60,8 +61,9 @@ func runCall(c call, stack stack) (any, ArErr) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
args := []any{}
|
args := []any{}
|
||||||
|
level := append(stack, map[string]any{})
|
||||||
for _, arg := range c.args {
|
for _, arg := range c.args {
|
||||||
resp, err := runVal(arg, stack)
|
resp, err := runVal(arg, level)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -69,9 +71,20 @@ func runCall(c call, stack stack) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
switch x := callable.(type) {
|
switch x := callable.(type) {
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
return x.FUNC(args...)
|
resp, err := x.FUNC(args...)
|
||||||
|
if err.EXISTS {
|
||||||
|
err = ArErr{err.TYPE, err.message, c.line, c.path, c.code, true}
|
||||||
|
}
|
||||||
|
return resp, err
|
||||||
case Callable:
|
case Callable:
|
||||||
return nil, ArErr{"Runtime Error", "cannot call a class", c.line, c.path, c.code, true}
|
if len(x.params) != len(args) {
|
||||||
|
return nil, ArErr{"Runtime Error", "expected " + fmt.Sprint(len(x.params)) + " arguments, got " + fmt.Sprint(len(args)), c.line, c.path, c.code, true}
|
||||||
|
}
|
||||||
|
level := map[string]any{}
|
||||||
|
for i, param := range x.params {
|
||||||
|
level[param] = args[i]
|
||||||
|
}
|
||||||
|
return runVal(x.run, append(stack, level))
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ package main
|
|||||||
type Callable struct {
|
type Callable struct {
|
||||||
name string
|
name string
|
||||||
params []string
|
params []string
|
||||||
code []any
|
run any
|
||||||
|
code string
|
||||||
stack stack
|
stack stack
|
||||||
line int
|
line int
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var commentCompile = makeRegex(".*//.*")
|
var commentCompile = makeRegex("(.|\n)*//(.|\n)*")
|
||||||
|
|
||||||
func isComment(code UNPARSEcode) bool {
|
func isComment(code UNPARSEcode) bool {
|
||||||
return commentCompile.MatchString(code.code)
|
return commentCompile.MatchString(code.code)
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ type ArErr struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func panicErr(err ArErr) {
|
func panicErr(err ArErr) {
|
||||||
fmt.Println(" File:", err.path+":"+fmt.Sprint(err.line))
|
if err.code != "" && err.line != 0 && err.path != "" {
|
||||||
fmt.Println(" " + err.code)
|
fmt.Println(" File:", err.path+":"+fmt.Sprint(err.line))
|
||||||
fmt.Println()
|
fmt.Println(" " + err.code)
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
fmt.Println(err.TYPE+":", err.message)
|
fmt.Println(err.TYPE+":", err.message)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ func importMod(realpath string, origin string, main bool) ArErr {
|
|||||||
if translationerr.EXISTS {
|
if translationerr.EXISTS {
|
||||||
return translationerr
|
return translationerr
|
||||||
}
|
}
|
||||||
_, runimeErr := run(translated, stack{vars})
|
global := map[string]any{}
|
||||||
|
_, runimeErr := run(translated, stack{vars, global})
|
||||||
if runimeErr.EXISTS {
|
if runimeErr.EXISTS {
|
||||||
return runimeErr
|
return runimeErr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
// args without the program path
|
// args without the program path
|
||||||
var Args = os.Args[1:]
|
var Args = os.Args[1:]
|
||||||
|
|
||||||
type stack = []map[string]variableValue
|
type stack = []map[string]any
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ex, e := os.Getwd()
|
ex, e := os.Getwd()
|
||||||
|
|||||||
20
src/map.go
20
src/map.go
@@ -7,7 +7,12 @@ import (
|
|||||||
|
|
||||||
type ArMap = map[any]any
|
type ArMap = map[any]any
|
||||||
|
|
||||||
var mapGetCompile = makeRegex(".+\\.([a-zA-Z_])([a-zA-Z0-9_])*( *)")
|
type ArClass struct {
|
||||||
|
value any
|
||||||
|
MAP ArMap
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapGetCompile = makeRegex("(.|\n)+\\.([a-zA-Z_])([a-zA-Z0-9_])*( *)")
|
||||||
|
|
||||||
type ArMapGet struct {
|
type ArMapGet struct {
|
||||||
VAL any
|
VAL any
|
||||||
@@ -39,6 +44,19 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m[key], ArErr{}
|
return m[key], ArErr{}
|
||||||
|
case ArClass:
|
||||||
|
if _, ok := m.MAP[key]; !ok {
|
||||||
|
return nil, ArErr{
|
||||||
|
"KeyError",
|
||||||
|
"key '" + fmt.Sprint(key) + "' not found",
|
||||||
|
r.line,
|
||||||
|
r.path,
|
||||||
|
r.code,
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m.MAP[key], ArErr{}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"TypeError",
|
"TypeError",
|
||||||
|
|||||||
31
src/negative.go
Normal file
31
src/negative.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
var negativeCompile = makeRegex(`( *)-(.|\n)+( *)`)
|
||||||
|
|
||||||
|
type negative struct {
|
||||||
|
VAL any
|
||||||
|
line int
|
||||||
|
code string
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNegative(code UNPARSEcode) bool {
|
||||||
|
return negativeCompile.MatchString(code.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseNegative(code UNPARSEcode, index int, codeline []UNPARSEcode) (negative, bool, ArErr, int) {
|
||||||
|
resp, worked, err, i := translateVal(UNPARSEcode{
|
||||||
|
code: strings.TrimSpace(code.code)[1:],
|
||||||
|
realcode: code.realcode,
|
||||||
|
line: code.line,
|
||||||
|
path: code.path,
|
||||||
|
}, index, codeline, false)
|
||||||
|
return negative{
|
||||||
|
VAL: resp,
|
||||||
|
line: code.line,
|
||||||
|
code: code.realcode,
|
||||||
|
path: code.path,
|
||||||
|
}, worked, err, i
|
||||||
|
}
|
||||||
@@ -7,15 +7,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type translateNumber struct {
|
type translateNumber struct {
|
||||||
number
|
number number
|
||||||
code string
|
code string
|
||||||
line int
|
line int
|
||||||
}
|
}
|
||||||
|
|
||||||
var numberCompile = makeRegex("( *)(\\-)?((([0-9]+(\\.[0-9]+)?)|(\\.[0-9]+))(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
var numberCompile = makeRegex("( *)(-)?((([0-9]+(\\.[0-9]+)?)|(\\.[0-9]+))(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
||||||
var binaryCompile = makeRegex("( *)(0b[10]+(.[10]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
var binaryCompile = makeRegex("( *)(-)?(0b[10]+(.\\[10]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
||||||
var hexCompile = makeRegex("( *)(0x[a-fA-F0-9]+(.[a-fA-F0-9]+)?)( *)")
|
var hexCompile = makeRegex("( *)(-)?(0x[a-fA-F0-9]+(\\.[a-fA-F0-9]+)?)( *)")
|
||||||
var octalCompile = makeRegex("( *)(0o[0-7]+(.[0-7]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
var octalCompile = makeRegex("( *)(-)?(0o[0-7]+(\\.[0-7]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
||||||
|
|
||||||
// a number type
|
// a number type
|
||||||
type number = *big.Rat
|
type number = *big.Rat
|
||||||
@@ -25,11 +25,6 @@ func newNumber() *big.Rat {
|
|||||||
return new(big.Rat)
|
return new(big.Rat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// converts a string into a number
|
|
||||||
func stringToNumber(str string) (*big.Rat, bool) {
|
|
||||||
return newNumber().SetString(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isNumber(code UNPARSEcode) bool {
|
func isNumber(code UNPARSEcode) bool {
|
||||||
return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code)
|
return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code)
|
||||||
}
|
}
|
||||||
@@ -89,10 +84,7 @@ var subscript = map[byte]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns translateNumber, success, error
|
// returns translateNumber, success, error
|
||||||
func parseNumber(code UNPARSEcode) (translateNumber, bool, ArErr, int) {
|
func parseNumber(code UNPARSEcode) (number, bool, ArErr, int) {
|
||||||
output, _ := newNumber().SetString(strings.TrimSpace(code.code))
|
output, _ := newNumber().SetString(strings.TrimSpace(code.code))
|
||||||
return translateNumber{
|
return output, true, ArErr{}, 1
|
||||||
number: output,
|
|
||||||
line: code.line,
|
|
||||||
}, true, ArErr{}, 1
|
|
||||||
}
|
}
|
||||||
|
|||||||
35
src/run.go
35
src/run.go
@@ -2,17 +2,44 @@ package main
|
|||||||
|
|
||||||
// returns (number|string|nil), error
|
// returns (number|string|nil), error
|
||||||
func runVal(line any, stack stack) (any, ArErr) {
|
func runVal(line any, stack stack) (any, ArErr) {
|
||||||
|
if len(stack) > 500 {
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "Stack overflow",
|
||||||
|
message: "the stack has exceeded 500 levels",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
switch x := line.(type) {
|
switch x := line.(type) {
|
||||||
case translateNumber:
|
case number:
|
||||||
return (x.number), ArErr{}
|
return x, ArErr{}
|
||||||
case translateString:
|
case string:
|
||||||
return (x.str), ArErr{}
|
return x, ArErr{}
|
||||||
case call:
|
case call:
|
||||||
return runCall(x, stack)
|
return runCall(x, stack)
|
||||||
case accessVariable:
|
case accessVariable:
|
||||||
return readVariable(x, stack)
|
return readVariable(x, stack)
|
||||||
case ArMapGet:
|
case ArMapGet:
|
||||||
return mapGet(x, stack)
|
return mapGet(x, stack)
|
||||||
|
case ArClass:
|
||||||
|
return x.MAP, ArErr{}
|
||||||
|
case setVariable:
|
||||||
|
return setVariableValue(x, stack)
|
||||||
|
case negative:
|
||||||
|
resp, err := runVal(x.VAL, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch y := resp.(type) {
|
||||||
|
case number:
|
||||||
|
return newNumber().Neg(y), ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "TypeError",
|
||||||
|
message: "cannot negate a non-number",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
case brackets:
|
||||||
|
return runVal(x.VAL, stack)
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,16 +32,13 @@ func unquoted(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns translateString, success, error
|
// returns translateString, success, error
|
||||||
func parseString(code UNPARSEcode) (translateString, bool, ArErr, int) {
|
func parseString(code UNPARSEcode) (string, bool, ArErr, int) {
|
||||||
trim := strings.Trim(code.code, " ")
|
trim := strings.Trim(code.code, " ")
|
||||||
|
|
||||||
unquoted, err := unquoted(trim)
|
unquoted, err := unquoted(trim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return translateString{}, false, ArErr{"Syntax Error", "invalid string", code.line, code.path, code.realcode, true}, 1
|
return "", false, ArErr{"Syntax Error", "invalid string", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return translateString{
|
return unquoted, true, ArErr{}, 1
|
||||||
str: unquoted,
|
|
||||||
line: code.line,
|
|
||||||
}, true, ArErr{}, 1
|
|
||||||
}
|
}
|
||||||
|
|||||||
216
src/time.go
Normal file
216
src/time.go
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var MicroSeconds = newNumber().SetInt64(1000000)
|
||||||
|
|
||||||
|
func ArTimeClass(N time.Time) ArClass {
|
||||||
|
return ArClass{
|
||||||
|
newNumber().Quo(newNumber().SetInt64(N.UnixMicro()), MicroSeconds),
|
||||||
|
ArMap{
|
||||||
|
"year": builtinFunc{
|
||||||
|
"year",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(int64(N.Year())), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"month": builtinFunc{
|
||||||
|
"month",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return N.Month().String(), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"day": builtinFunc{
|
||||||
|
"day",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(int64(N.Day())), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"hour": builtinFunc{
|
||||||
|
"hour",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(int64(N.Hour())), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"minute": builtinFunc{
|
||||||
|
"minute",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(int64(N.Minute())), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"second": builtinFunc{
|
||||||
|
"second",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(int64(N.Second())), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"nanosecond": builtinFunc{
|
||||||
|
"nanosecond",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(int64(N.Nanosecond())), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"weekday": builtinFunc{
|
||||||
|
"weekday",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return N.Weekday().String(), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"yearDay": builtinFunc{
|
||||||
|
"yearDay",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(int64(N.YearDay())), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"unix": builtinFunc{
|
||||||
|
"unix",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(N.Unix()), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"unixNano": builtinFunc{
|
||||||
|
"unixNano",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(N.UnixNano()), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"unixMilli": builtinFunc{
|
||||||
|
"unixMilli",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(N.UnixMilli()), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"unixMicro": builtinFunc{
|
||||||
|
"unixMicro",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
return newNumber().SetInt64(N.UnixMicro()), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"format": builtinFunc{
|
||||||
|
"date",
|
||||||
|
func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return N.Format(time.UnixDate), ArErr{}
|
||||||
|
}
|
||||||
|
return N.Format(a[0].(string)), ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ArTime = map[any]any{
|
||||||
|
"snooze": builtinFunc{"snooze", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) > 0 {
|
||||||
|
float, _ := a[0].(number).Float64()
|
||||||
|
time.Sleep(time.Duration(float*1000000000) * time.Nanosecond)
|
||||||
|
}
|
||||||
|
return nil, ArErr{}
|
||||||
|
}},
|
||||||
|
"now": builtinFunc{"now", func(a ...any) (any, ArErr) {
|
||||||
|
return ArTimeClass(time.Now()), ArErr{}
|
||||||
|
}},
|
||||||
|
"parse": builtinFunc{"parse", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) == 1 {
|
||||||
|
N, err := time.Parse(time.UnixDate, a[0].(string))
|
||||||
|
if err != nil {
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ArTimeClass(N), ArErr{}
|
||||||
|
} else if len(a) > 1 {
|
||||||
|
N, err := time.Parse(a[0].(string), a[1].(string))
|
||||||
|
if err != nil {
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: err.Error(),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ArTimeClass(N), ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: "parse requires 2 arguments",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
"parseInLocation": builtinFunc{"parseInLocation", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) > 2 {
|
||||||
|
N, err := time.ParseInLocation(a[0].(string), a[1].(string), time.Local)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: err.Error(),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ArTimeClass(N), ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: "parseInLocation requires 3 arguments",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"date": builtinFunc{"date", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) > 0 {
|
||||||
|
N, err := time.Parse(time.UnixDate, a[0].(string))
|
||||||
|
if err != nil {
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: err.Error(),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ArTimeClass(N), ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: "date requires 1 argument",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Unix": builtinFunc{"Unix", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) > 1 {
|
||||||
|
sec, _ := a[0].(number).Float64()
|
||||||
|
nsec, _ := a[1].(number).Float64()
|
||||||
|
return ArTimeClass(time.Unix(int64(sec), int64(nsec))), ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: "Unix requires 2 arguments",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"UnixMilli": builtinFunc{"UnixMilli", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) > 0 {
|
||||||
|
msec, _ := a[0].(number).Float64()
|
||||||
|
return ArTimeClass(time.UnixMilli(int64(msec))), ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: "UnixMilli requires 1 argument",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"UnixMicro": builtinFunc{"UnixMicro", func(a ...any) (any, ArErr) {
|
||||||
|
if len(a) > 0 {
|
||||||
|
usec, _ := a[0].(number).Float64()
|
||||||
|
return ArTimeClass(time.UnixMicro(int64(usec))), ArErr{}
|
||||||
|
}
|
||||||
|
return nil, ArErr{
|
||||||
|
TYPE: "ArErr",
|
||||||
|
message: "UnixMicro requires 1 argument",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func anyToArgon(x any, quote bool) string {
|
func anyToArgon(x any, quote bool) string {
|
||||||
@@ -22,8 +23,31 @@ func anyToArgon(x any, quote bool) string {
|
|||||||
} else if math.IsInf(num, -1) {
|
} else if math.IsInf(num, -1) {
|
||||||
return "-infinity"
|
return "-infinity"
|
||||||
} else {
|
} else {
|
||||||
return strconv.FormatFloat(num, 'f', -1, 64)
|
return numberToString(x, 0)
|
||||||
}
|
}
|
||||||
|
case bool:
|
||||||
|
return strconv.FormatBool(x)
|
||||||
|
case nil:
|
||||||
|
return "null"
|
||||||
|
case ArMap:
|
||||||
|
keys := make([]any, len(x))
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for k := range x {
|
||||||
|
keys[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
output := []string{}
|
||||||
|
for _, key := range keys {
|
||||||
|
output = append(output, anyToArgon(key, true)+": "+anyToArgon(x[key], true))
|
||||||
|
}
|
||||||
|
return "{" + strings.Join(output, ", ") + "}"
|
||||||
|
case builtinFunc:
|
||||||
|
return "<builtin function " + x.name + ">"
|
||||||
|
case Callable:
|
||||||
|
return "<function " + x.name + ">"
|
||||||
|
case ArClass:
|
||||||
|
return anyToArgon(x.value, false)
|
||||||
default:
|
default:
|
||||||
return fmt.Sprint(x)
|
return fmt.Sprint(x)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type UNPARSEcode struct {
|
|||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns (translateNumber | translateString| nil), success, error
|
// returns (translateNumber | translateString| nil), success, error, step
|
||||||
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine bool) (any, bool, ArErr, int) {
|
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine bool) (any, bool, ArErr, int) {
|
||||||
if isLine {
|
if isLine {
|
||||||
if isBlank(code) {
|
if isBlank(code) {
|
||||||
@@ -19,14 +19,20 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isCall(code) {
|
if isSetVariable(code) {
|
||||||
|
return parseSetVariable(code, index, codelines)
|
||||||
|
} else if isBrackets(code) {
|
||||||
|
return parseBrackets(code, index, codelines)
|
||||||
|
} else if isNumber(code) {
|
||||||
|
return parseNumber(code)
|
||||||
|
} else if isNegative(code) {
|
||||||
|
return parseNegative(code, index, codelines)
|
||||||
|
} else if isCall(code) {
|
||||||
return parseCall(code, index, codelines)
|
return parseCall(code, index, codelines)
|
||||||
} else if isVariable(code) {
|
} else if isVariable(code) {
|
||||||
return parseVariable(code)
|
return parseVariable(code)
|
||||||
} else if isMapGet(code) {
|
} else if isMapGet(code) {
|
||||||
return mapGetParse(code, index, codelines)
|
return mapGetParse(code, index, codelines)
|
||||||
} else if isNumber(code) {
|
|
||||||
return parseNumber(code)
|
|
||||||
} else if isString(code) {
|
} else if isString(code) {
|
||||||
return parseString(code)
|
return parseString(code)
|
||||||
}
|
}
|
||||||
@@ -36,9 +42,9 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine b
|
|||||||
// returns [](translateNumber | translateString), error
|
// returns [](translateNumber | translateString), error
|
||||||
func translate(codelines []UNPARSEcode) ([]any, ArErr) {
|
func translate(codelines []UNPARSEcode) ([]any, ArErr) {
|
||||||
translated := []any{}
|
translated := []any{}
|
||||||
for i, code := range codelines {
|
for i := 0; i < len(codelines); {
|
||||||
val, _, err, _ := translateVal(code, i, codelines, true)
|
val, _, err, step := translateVal(codelines[i], i, codelines, true)
|
||||||
|
i += step
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ func typeof(val any) string {
|
|||||||
return "function"
|
return "function"
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
return "function"
|
return "function"
|
||||||
|
case ArMap:
|
||||||
|
return "map"
|
||||||
}
|
}
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var variableCompile = makeRegex(`([a-zA-Z_])([a-zA-Z0-9_])*`)
|
var variableCompile = makeRegex(`( *)([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*( *)`)
|
||||||
|
var setVariableCompile = makeRegex(`( *)(let( +))?([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*(\(( *)((([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)(( *)\,( *)([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)*)?( *)\))?( *)=(.|\n)+`)
|
||||||
|
|
||||||
var blockedVariableNames = map[string]bool{
|
var blockedVariableNames = map[string]bool{
|
||||||
"if": true,
|
"if": true,
|
||||||
@@ -21,12 +22,6 @@ var blockedVariableNames = map[string]bool{
|
|||||||
"do": true,
|
"do": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
type variableValue struct {
|
|
||||||
VAL any
|
|
||||||
EXISTS any
|
|
||||||
origin string
|
|
||||||
}
|
|
||||||
|
|
||||||
type accessVariable struct {
|
type accessVariable struct {
|
||||||
name string
|
name string
|
||||||
line int
|
line int
|
||||||
@@ -34,6 +29,17 @@ type accessVariable struct {
|
|||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type setVariable struct {
|
||||||
|
TYPE string
|
||||||
|
name string
|
||||||
|
value any
|
||||||
|
function bool
|
||||||
|
params []string
|
||||||
|
line int
|
||||||
|
code string
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
func isVariable(code UNPARSEcode) bool {
|
func isVariable(code UNPARSEcode) bool {
|
||||||
return variableCompile.MatchString(code.code)
|
return variableCompile.MatchString(code.code)
|
||||||
}
|
}
|
||||||
@@ -49,8 +55,71 @@ func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
|
|||||||
func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
||||||
for i := len(stack) - 1; i >= 0; i-- {
|
for i := len(stack) - 1; i >= 0; i-- {
|
||||||
if val, ok := stack[i][v.name]; ok {
|
if val, ok := stack[i][v.name]; ok {
|
||||||
return val.VAL, ArErr{}
|
return val, ArErr{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Runtime Error", "variable \"" + v.name + "\" does not exist", v.line, v.path, v.code, true}
|
return nil, ArErr{"Runtime Error", "variable \"" + v.name + "\" does not exist", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isSetVariable(code UNPARSEcode) bool {
|
||||||
|
return setVariableCompile.MatchString(code.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode) (setVariable, bool, ArErr, int) {
|
||||||
|
trim := strings.TrimSpace(code.code)
|
||||||
|
equalsplit := strings.SplitN(trim, "=", 2)
|
||||||
|
spacesplit := strings.SplitN(equalsplit[0], " ", 2)
|
||||||
|
TYPE := "auto"
|
||||||
|
name := strings.TrimSpace(equalsplit[0])
|
||||||
|
params := []string{}
|
||||||
|
function := false
|
||||||
|
if spacesplit[0] == "let" {
|
||||||
|
TYPE = "let"
|
||||||
|
name = strings.TrimSpace(spacesplit[1])
|
||||||
|
}
|
||||||
|
if name[len(name)-1] == ')' {
|
||||||
|
function = true
|
||||||
|
bracketsplit := strings.SplitN(name, "(", 2)
|
||||||
|
name = bracketsplit[0]
|
||||||
|
params = strings.Split(bracketsplit[1][:len(bracketsplit[1])-1], ",")
|
||||||
|
for i := 0; i < len(params); i++ {
|
||||||
|
params[i] = strings.TrimSpace(params[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if blockedVariableNames[name] {
|
||||||
|
return setVariable{}, false, ArErr{"Naming Error", "Naming Error: \"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1
|
||||||
|
}
|
||||||
|
value, success, err, i := translateVal(UNPARSEcode{code: equalsplit[1], realcode: code.realcode, line: code.line, path: code.path}, index, lines, true)
|
||||||
|
if !success {
|
||||||
|
return setVariable{}, false, err, i
|
||||||
|
}
|
||||||
|
return setVariable{TYPE: TYPE, name: name, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i
|
||||||
|
}
|
||||||
|
|
||||||
|
func setVariableValue(v setVariable, stack stack) (any, ArErr) {
|
||||||
|
var resp any
|
||||||
|
if v.function {
|
||||||
|
resp = Callable{v.name, v.params, v.value, v.code, stack, v.line}
|
||||||
|
} else {
|
||||||
|
respp, err := runVal(v.value, stack)
|
||||||
|
if err.EXISTS {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp = respp
|
||||||
|
}
|
||||||
|
if v.TYPE == "let" {
|
||||||
|
if _, ok := stack[len(stack)-1][v.name]; ok {
|
||||||
|
return stack, ArErr{"Runtime Error", "variable \"" + v.name + "\" already exists", v.line, v.path, v.code, true}
|
||||||
|
}
|
||||||
|
stack[len(stack)-1][v.name] = resp
|
||||||
|
} else {
|
||||||
|
for i := len(stack) - 1; i >= 0; i-- {
|
||||||
|
if _, ok := stack[i][v.name]; ok {
|
||||||
|
stack[i][v.name] = resp
|
||||||
|
return stack, ArErr{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack[len(stack)-1][v.name] = resp
|
||||||
|
}
|
||||||
|
return resp, ArErr{}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user