mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
add functions and variables name
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
@echo off
|
||||
|
||||
go build -o bin/Argon-v3.exe ./src
|
||||
go build -o bin/argon.exe ./src
|
||||
@@ -10,6 +10,7 @@ ARGON 3 is a math-driven programming language designed to make code easy to read
|
||||
## 📚 Features
|
||||
|
||||
- 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.
|
||||
- All numbers are stored as rational numbers, preventing precision errors.
|
||||
- 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.
|
||||
- Interpreted: Argon 3 is an interpreted language, so you don't need to compile your code before running it.
|
||||
- Cross-platform: Argon 3 can be run on any platform that has an interpreter for it.
|
||||
|
||||
2
spec.md
2
spec.md
@@ -64,7 +64,7 @@ output:
|
||||
f(10) = 121
|
||||
```
|
||||
|
||||
if the function does not return, then the value returned is `unknown`
|
||||
if the function does not return, then the value returned is `null`
|
||||
|
||||
---
|
||||
|
||||
|
||||
34
src/built-in-functions.go
Normal file
34
src/built-in-functions.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type builtinFunc struct {
|
||||
name string
|
||||
FUNC func(...any) (any, ArErr)
|
||||
}
|
||||
|
||||
func ArgonLog(args ...any) (any, ArErr) {
|
||||
output := []any{}
|
||||
for i := 0; i < len(args); i++ {
|
||||
output = append(output, anyToArgon(args[i], false))
|
||||
}
|
||||
fmt.Println(output...)
|
||||
return nil, ArErr{}
|
||||
}
|
||||
|
||||
func ArgonAdd(args ...any) (any, ArErr) {
|
||||
return reduce(func(x any, y any) any {
|
||||
return newNumber().Add(x.(number), y.(number))
|
||||
}, args), ArErr{}
|
||||
}
|
||||
func ArgonDiv(args ...any) (any, ArErr) {
|
||||
return reduce(func(x any, y any) any {
|
||||
return newNumber().Quo(y.(number), x.(number))
|
||||
}, args), ArErr{}
|
||||
}
|
||||
|
||||
func ArgonMult(args ...any) (any, ArErr) {
|
||||
return reduce(func(x any, y any) any {
|
||||
return newNumber().Mul(y.(number), x.(number))
|
||||
}, args), ArErr{}
|
||||
}
|
||||
27
src/built-ins.go
Normal file
27
src/built-ins.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
var vars = map[string]variableValue{}
|
||||
|
||||
func init() {
|
||||
vars["log"] = variableValue{
|
||||
EXISTS: true,
|
||||
VAL: builtinFunc{"log", ArgonLog},
|
||||
}
|
||||
vars["add"] = variableValue{
|
||||
EXISTS: true,
|
||||
VAL: builtinFunc{"add", ArgonAdd},
|
||||
}
|
||||
vars["div"] = variableValue{
|
||||
EXISTS: true,
|
||||
VAL: builtinFunc{"div", ArgonDiv},
|
||||
}
|
||||
vars["mult"] = variableValue{
|
||||
EXISTS: true,
|
||||
VAL: builtinFunc{"mult", ArgonMult},
|
||||
}
|
||||
pi, _ := newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
|
||||
vars["PI"] = variableValue{
|
||||
EXISTS: true,
|
||||
VAL: pi,
|
||||
}
|
||||
}
|
||||
76
src/call.go
Normal file
76
src/call.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var callCompile = makeRegex("( *).+\\(.*\\)( *)")
|
||||
|
||||
type call struct {
|
||||
callable any
|
||||
args []any
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
func isCall(code UNPARSEcode) bool {
|
||||
return callCompile.MatchString(code.code)
|
||||
}
|
||||
|
||||
func parseCall(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) {
|
||||
trim := strings.TrimSpace(code.code)
|
||||
trim = trim[:len(trim)-1]
|
||||
splitby := strings.Split(trim, "(")
|
||||
|
||||
var works bool
|
||||
var callable any
|
||||
var arguments []any
|
||||
for i := 1; i < len(splitby); i++ {
|
||||
name := strings.Join(splitby[0:i], "(")
|
||||
argstr := strings.Join(splitby[i:], "(")
|
||||
args, success, argserr := getValuesFromCommas(argstr, index, codelines)
|
||||
arguments = args
|
||||
if !success {
|
||||
if i == len(splitby)-1 {
|
||||
return nil, false, argserr, 1
|
||||
}
|
||||
continue
|
||||
}
|
||||
resp, worked, _, _ := translateVal(UNPARSEcode{code: name, realcode: code.realcode, line: index + 1, path: code.path}, index, codelines, false)
|
||||
if !worked {
|
||||
if i == len(splitby)-1 {
|
||||
return nil, false, ArErr{"Syntax Error", "invalid callable", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
continue
|
||||
}
|
||||
works = true
|
||||
callable = resp
|
||||
break
|
||||
}
|
||||
if !works {
|
||||
return nil, false, ArErr{"Syntax Error", "invalid call", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
return call{callable: callable, args: arguments, line: code.line, code: code.code}, true, ArErr{}, 1
|
||||
}
|
||||
|
||||
func runCall(c call, stack []map[string]variableValue) (any, ArErr) {
|
||||
callable, err := runVal(c.callable, stack)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
args := []any{}
|
||||
for _, arg := range c.args {
|
||||
resp, err := runVal(arg, stack)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
args = append(args, resp)
|
||||
}
|
||||
switch x := callable.(type) {
|
||||
case builtinFunc:
|
||||
return x.FUNC(args...)
|
||||
case Callable:
|
||||
return nil, ArErr{"Runtime Error", "cannot call a class", c.line, "", c.code, true}
|
||||
}
|
||||
return nil, ArErr{"Runtime Error", typeof(callable) + "' is not callable", c.line, "", c.code, true}
|
||||
}
|
||||
9
src/callable.go
Normal file
9
src/callable.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
type Callable struct {
|
||||
name string
|
||||
params []string
|
||||
code []any
|
||||
stack []map[string]variableValue
|
||||
line int
|
||||
}
|
||||
27
src/commaseperate.go
Normal file
27
src/commaseperate.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getValuesFromCommas(str string, index int, codelines []UNPARSEcode) ([]any, bool, ArErr) {
|
||||
// make a function which takes a string of code and returns a translated values
|
||||
str = strings.Trim(str, " ")
|
||||
commasplit := strings.Split(str, ",")
|
||||
temp := []string{}
|
||||
arguments := []any{}
|
||||
if str != "" {
|
||||
for i, arg := range commasplit {
|
||||
temp = append(temp, arg)
|
||||
test := strings.TrimSpace(strings.Join(temp, ","))
|
||||
resp, worked, _, _ := translateVal(UNPARSEcode{code: test, realcode: codelines[index].realcode, line: index + 1, path: codelines[index].path}, index, codelines, false)
|
||||
if worked {
|
||||
arguments = append(arguments, resp)
|
||||
temp = []string{}
|
||||
} else if i == len(commasplit)-1 {
|
||||
return nil, false, ArErr{"Syntax Error", "invalid argument", codelines[index].line, codelines[index].path, codelines[index].realcode, true}
|
||||
}
|
||||
}
|
||||
}
|
||||
return arguments, true, ArErr{}
|
||||
}
|
||||
@@ -1,7 +1,29 @@
|
||||
package main
|
||||
|
||||
var commentCompile = makeRegex("( *)//.*")
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var commentCompile = makeRegex(".*//.*")
|
||||
|
||||
func isComment(code UNPARSEcode) bool {
|
||||
return commentCompile.MatchString(code.code)
|
||||
}
|
||||
|
||||
func isBlank(code UNPARSEcode) bool {
|
||||
return strings.TrimSpace(code.code) == ""
|
||||
}
|
||||
|
||||
func parseComment(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr) {
|
||||
split := strings.Split(code.code, "//")
|
||||
temp := []string{}
|
||||
for i := 0; i < len(split)-1; i++ {
|
||||
temp = append(temp, split[i])
|
||||
joined := strings.Join(temp, "//")
|
||||
resp, worked, _, _ := translateVal(UNPARSEcode{code: joined, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, true)
|
||||
if worked {
|
||||
return resp, true, ArErr{}
|
||||
}
|
||||
}
|
||||
return nil, false, ArErr{"Syntax Error", "invalid comment", code.line, code.path, code.realcode, true}
|
||||
}
|
||||
|
||||
23
src/error.go
Normal file
23
src/error.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type ArErr struct {
|
||||
TYPE string
|
||||
message string
|
||||
line int
|
||||
path string
|
||||
code string
|
||||
EXISTS bool
|
||||
}
|
||||
|
||||
func panicErr(err ArErr) {
|
||||
fmt.Println(" File:", err.path+":"+fmt.Sprint(err.line))
|
||||
fmt.Println(" " + err.code)
|
||||
fmt.Println()
|
||||
fmt.Println(err.TYPE+":", err.message)
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -32,7 +32,8 @@ func readFile(path string) []UNPARSEcode {
|
||||
output := []UNPARSEcode{}
|
||||
line := 1
|
||||
for scanner.Scan() {
|
||||
output = append(output, UNPARSEcode{scanner.Text(), line})
|
||||
text := scanner.Text()
|
||||
output = append(output, UNPARSEcode{text, text, line, path})
|
||||
line++
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ func readFile(path string) []UNPARSEcode {
|
||||
return output
|
||||
}
|
||||
|
||||
func importMod(realpath string, origin string, main bool) string {
|
||||
func importMod(realpath string, origin string, main bool) ArErr {
|
||||
extention := filepath.Ext(realpath)
|
||||
path := realpath
|
||||
if extention == "" {
|
||||
@@ -51,11 +52,11 @@ func importMod(realpath string, origin string, main bool) string {
|
||||
}
|
||||
ex, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
return ArErr{"Import Error", err.Error(), 0, realpath, "", true}
|
||||
}
|
||||
executable, err := os.Executable()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
return ArErr{"Import Error", err.Error(), 0, realpath, "", true}
|
||||
}
|
||||
executable = filepath.Dir(executable)
|
||||
isABS := filepath.IsAbs(path)
|
||||
@@ -89,14 +90,17 @@ func importMod(realpath string, origin string, main bool) string {
|
||||
}
|
||||
|
||||
if !found {
|
||||
return "File does not exist: " + realpath
|
||||
return ArErr{"Import Error", "File does not exist: " + realpath, 0, realpath, "", true}
|
||||
}
|
||||
codelines := readFile(p)
|
||||
|
||||
translated, translationerr := translate(codelines)
|
||||
if translationerr != "" {
|
||||
if translationerr.EXISTS {
|
||||
return translationerr
|
||||
}
|
||||
run(translated)
|
||||
return ""
|
||||
_, runimeErr := run(translated, []map[string]variableValue{vars})
|
||||
if runimeErr.EXISTS {
|
||||
return runimeErr
|
||||
}
|
||||
return ArErr{}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
var Args = os.Args[1:]
|
||||
|
||||
func main() {
|
||||
|
||||
ex, e := os.Getwd()
|
||||
if e != nil {
|
||||
panic(e)
|
||||
@@ -17,7 +16,7 @@ func main() {
|
||||
panic("No file specified")
|
||||
}
|
||||
err := importMod(Args[0], ex, true)
|
||||
if err != "" {
|
||||
panic(err)
|
||||
if err.EXISTS {
|
||||
panicErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,16 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var numberCompile = makeRegex("( *)((\\-)?(([0-9]*(\\.[0-9]+)?)(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)|(0b[10]+(.[10]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)|(0x[a-fA-F0-9]+(.[a-fA-F0-9]+)?)|(0o[0-7]+(.[0-7]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?))( *)")
|
||||
type translateNumber struct {
|
||||
number
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
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 hexCompile = makeRegex("( *)(0x[a-fA-F0-9]+(.[a-fA-F0-9]+)?)( *)")
|
||||
var octalCompile = makeRegex("( *)(0o[0-7]+(.[0-7]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
||||
|
||||
// a number type
|
||||
type number = *big.Rat
|
||||
@@ -22,7 +31,7 @@ func stringToNumber(str string) (*big.Rat, bool) {
|
||||
}
|
||||
|
||||
func isNumber(code UNPARSEcode) bool {
|
||||
return numberCompile.MatchString(code.code)
|
||||
return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code)
|
||||
}
|
||||
|
||||
// converts a number type to a string
|
||||
@@ -80,10 +89,10 @@ var subscript = map[byte]string{
|
||||
}
|
||||
|
||||
// returns translateNumber, success, error
|
||||
func parseNumber(code UNPARSEcode) (translateNumber, bool, string) {
|
||||
output, _ := newNumber().SetString(code.code)
|
||||
func parseNumber(code UNPARSEcode) (translateNumber, bool, ArErr, int) {
|
||||
output, _ := newNumber().SetString(strings.TrimSpace(code.code))
|
||||
return translateNumber{
|
||||
number: output,
|
||||
line: code.line,
|
||||
}, true, ""
|
||||
}, true, ArErr{}, 1
|
||||
}
|
||||
|
||||
9
src/reduce.go
Normal file
9
src/reduce.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
func reduce[T any](reducer func(x T, y T) T, arr []T) T {
|
||||
result := arr[0]
|
||||
for i := 1; i < len(arr); i++ {
|
||||
result = reducer(arr[i], result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
25
src/run.go
25
src/run.go
@@ -1,24 +1,27 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func runLine(line any) (any, string) {
|
||||
switch line.(type) {
|
||||
// returns (number|string|nil), error
|
||||
func runVal(line any, stack []map[string]variableValue) (any, ArErr) {
|
||||
switch x := line.(type) {
|
||||
case translateNumber:
|
||||
return (numberToString(line.(translateNumber).number, 0)), ""
|
||||
return (x.number), ArErr{}
|
||||
case translateString:
|
||||
return (line.(translateString).str), ""
|
||||
return (x.str), ArErr{}
|
||||
case call:
|
||||
return runCall(x, stack)
|
||||
case accessVariable:
|
||||
return readVariable(x, stack)
|
||||
}
|
||||
return nil, "Error: invalid code on line " + fmt.Sprint(line.(translateNumber).line) + ": " + line.(translateNumber).code
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// returns error
|
||||
func run(translated []any) (any, string) {
|
||||
func run(translated []any, stack []map[string]variableValue) (any, ArErr) {
|
||||
for _, val := range translated {
|
||||
_, err := runLine(val)
|
||||
if err != "" {
|
||||
_, err := runVal(val, stack)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, ""
|
||||
return nil, ArErr{}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type translateString struct {
|
||||
str string
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
var stringCompile = makeRegex("(( *)\"((\\\\([a-z\\\"'`]))|[^\\\"])*\"( *))|(( *)'((\\\\([a-z\\'\"`]))|[^\\'])*'( *))")
|
||||
|
||||
func isString(code UNPARSEcode) bool {
|
||||
@@ -27,16 +32,16 @@ func unquoted(
|
||||
}
|
||||
|
||||
// returns translateString, success, error
|
||||
func parseString(code UNPARSEcode) (translateString, bool, string) {
|
||||
func parseString(code UNPARSEcode) (translateString, bool, ArErr, int) {
|
||||
trim := strings.Trim(code.code, " ")
|
||||
|
||||
unquoted, err := unquoted(trim)
|
||||
if err != nil {
|
||||
return translateString{}, false, "Syntax Error: invalid string on line " + fmt.Sprint(code.line) + ": " + code.code
|
||||
return translateString{}, false, ArErr{"Syntax Error", "invalid string", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
|
||||
return translateString{
|
||||
str: unquoted,
|
||||
line: code.line,
|
||||
}, true, ""
|
||||
}, true, ArErr{}, 1
|
||||
}
|
||||
|
||||
30
src/to-argon.go
Normal file
30
src/to-argon.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func anyToArgon(x any, quote bool) string {
|
||||
switch x := x.(type) {
|
||||
case string:
|
||||
if !quote {
|
||||
return x
|
||||
}
|
||||
return strconv.Quote(x)
|
||||
case number:
|
||||
num, _ := x.Float64()
|
||||
if math.IsNaN(num) {
|
||||
return "NaN"
|
||||
} else if math.IsInf(num, 1) {
|
||||
return "infinity"
|
||||
} else if math.IsInf(num, -1) {
|
||||
return "-infinity"
|
||||
} else {
|
||||
return strconv.FormatFloat(num, 'f', -1, 64)
|
||||
}
|
||||
default:
|
||||
return fmt.Sprint(x)
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
type UNPARSEcode struct {
|
||||
code string
|
||||
realcode string
|
||||
line int
|
||||
path string
|
||||
}
|
||||
|
||||
// returns (translateNumber | translateString), success, error
|
||||
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine bool) (any, bool, string) {
|
||||
// returns (translateNumber | translateString| nil), success, error
|
||||
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine bool) (any, bool, ArErr, int) {
|
||||
if isLine {
|
||||
if isComment(code) {
|
||||
return nil, true, ""
|
||||
if isBlank(code) {
|
||||
return nil, true, ArErr{}, 1
|
||||
} else if isComment(code) {
|
||||
resp, worked, err := parseComment(code, index, codelines)
|
||||
if worked {
|
||||
return resp, worked, err, 1
|
||||
}
|
||||
}
|
||||
|
||||
if isNumber(code) {
|
||||
}
|
||||
if isCall(code) {
|
||||
return parseCall(code, index, codelines)
|
||||
} else if isVariable(code) {
|
||||
return parseVariable(code)
|
||||
} else if isNumber(code) {
|
||||
return parseNumber(code)
|
||||
} else if isString(code) {
|
||||
return parseString(code)
|
||||
}
|
||||
if isLine {
|
||||
return nil, false, "Syntax Error: invalid code on line " + fmt.Sprint(code.line) + ": " + code.code
|
||||
}
|
||||
return nil, false, ""
|
||||
return nil, false, ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
|
||||
// returns [](translateNumber | translateString), error
|
||||
func translate(codelines []UNPARSEcode) ([]any, string) {
|
||||
func translate(codelines []UNPARSEcode) ([]any, ArErr) {
|
||||
translated := []any{}
|
||||
for i, code := range codelines {
|
||||
val, _, err := translateVal(code, i, codelines, true)
|
||||
val, _, err, _ := translateVal(code, i, codelines, true)
|
||||
|
||||
if err != "" {
|
||||
log.Fatal(err)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if val == nil {
|
||||
@@ -39,5 +45,5 @@ func translate(codelines []UNPARSEcode) ([]any, string) {
|
||||
}
|
||||
translated = append(translated, val)
|
||||
}
|
||||
return translated, ""
|
||||
return translated, ArErr{}
|
||||
}
|
||||
|
||||
19
src/typeof.go
Normal file
19
src/typeof.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
func typeof(val any) string {
|
||||
switch val.(type) {
|
||||
case number:
|
||||
return "number"
|
||||
case string:
|
||||
return "string"
|
||||
case nil:
|
||||
return "null"
|
||||
case bool:
|
||||
return "boolean"
|
||||
case Callable:
|
||||
return "function"
|
||||
case builtinFunc:
|
||||
return "function"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
18
src/types.go
18
src/types.go
@@ -1,18 +0,0 @@
|
||||
package main
|
||||
|
||||
type UNPARSEcode struct {
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
type translateNumber struct {
|
||||
number
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
type translateString struct {
|
||||
str string
|
||||
code string
|
||||
line int
|
||||
}
|
||||
56
src/variable.go
Normal file
56
src/variable.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var variableCompile = makeRegex(`([a-zA-Z_])([a-zA-Z0-9_])*`)
|
||||
|
||||
var blockedVariableNames = map[string]bool{
|
||||
"if": true,
|
||||
"else": true,
|
||||
"elif": true,
|
||||
"while": true,
|
||||
"for": true,
|
||||
"break": true,
|
||||
"continue": true,
|
||||
"return": true,
|
||||
"let": true,
|
||||
"import": true,
|
||||
"from": true,
|
||||
"do": true,
|
||||
}
|
||||
|
||||
type variableValue struct {
|
||||
VAL any
|
||||
EXISTS any
|
||||
origin string
|
||||
}
|
||||
|
||||
type accessVariable struct {
|
||||
name string
|
||||
line int
|
||||
code string
|
||||
path string
|
||||
}
|
||||
|
||||
func isVariable(code UNPARSEcode) bool {
|
||||
return variableCompile.MatchString(code.code)
|
||||
}
|
||||
|
||||
func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
|
||||
name := strings.TrimSpace(code.code)
|
||||
if blockedVariableNames[name] {
|
||||
return accessVariable{}, false, ArErr{"Naming Error", "Naming Error: \"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
return accessVariable{name: name, code: code.code, line: code.line}, true, ArErr{}, 1
|
||||
}
|
||||
|
||||
func readVariable(v accessVariable, stack []map[string]variableValue) (any, ArErr) {
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
if val, ok := stack[i][v.name]; ok {
|
||||
return val.VAL, ArErr{}
|
||||
}
|
||||
}
|
||||
return nil, ArErr{"Runtime Error", "variable \"" + v.name + "\" does not exist", v.line, v.path, v.code, true}
|
||||
}
|
||||
Reference in New Issue
Block a user