mirror of
https://github.com/Open-Argon/argon-v2.git
synced 2026-10-28 09:44:03 +00:00
844 lines
21 KiB
Go
844 lines
21 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var anyAndNewline = "((.)|(\\n))"
|
|
var variableOnly = "([a-zA-Z_])([a-zA-Z0-9_])*"
|
|
var variableWithIndexes = variableOnly + "(\\[" + anyAndNewline + "+\\]|\\." + variableOnly + ")*"
|
|
var stringCompile = makeRegex("(( *)\"((\\\\([a-z\\\"'`]))|[^\\\"])*\"( *))|(( *)'((\\\\([a-z\\'\"`]))|[^\\'])*'( *))|(( *)(`(\\\\[a-z\\\"'`\\n]|[^\\`])*`)( *))")
|
|
var numberCompile = makeRegex("( *)(\\-)?(([0-9]*(\\.[0-9]+)?)(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)( *)")
|
|
var whileCompile = makeRegex("( *)(while( )+" + anyAndNewline + "+( )+\\[" + anyAndNewline + "*)( *)")
|
|
var subCompile = makeRegex("( *)(sub( )+" + variableOnly + "\\(" + anyAndNewline + "*\\)( )+\\[" + anyAndNewline + "*)( *)")
|
|
var ifCompile = makeRegex("( *)(if( )+" + anyAndNewline + "+( )+\\[" + anyAndNewline + "*)( *)")
|
|
var elseifCompile = makeRegex("( *)(\\]( )+else( )+if( )+" + anyAndNewline + "+( )+\\[" + anyAndNewline + "*)( *)")
|
|
var elseCompile = makeRegex("( *)\\]( )+else( )+\\[" + anyAndNewline + "*( *)")
|
|
var closeCompile = makeRegex("( *)\\]( *)")
|
|
var switchCloseCompile = makeRegex("( *)" + anyAndNewline + "*\\]" + anyAndNewline + "*\\[" + anyAndNewline + "*( *)")
|
|
var importCompile = makeRegex("( *)((import " + anyAndNewline + "+)|(from( +)" + anyAndNewline + "+( +)import( +)(( *)" + variableOnly + "( *)(\\,( *)" + variableOnly + "( *))*)))( *)")
|
|
var bracketsCompile = makeRegex("( *)\\(" + anyAndNewline + "*\\)( *)")
|
|
var functionCompile = makeRegex("( *)" + anyAndNewline + "+\\(" + anyAndNewline + "*\\)( *)")
|
|
var indexCompile = makeRegex("( *)" + anyAndNewline + "+\\[" + anyAndNewline + "+\\]( *)")
|
|
var variableTextCompile = makeRegex("( *)" + variableWithIndexes + "( *)")
|
|
var variableonlyCompile = makeRegex(variableOnly)
|
|
var setVariableCompile = makeRegex("( *)(((const|var) (" + variableOnly + "( *))=( *)" + anyAndNewline + "+)|(( *)" + variableOnly + "( *))(( *)=( *)" + anyAndNewline + "+))( *)")
|
|
var callErrorCompile = makeRegex("( *)(error(( )+" + anyAndNewline + "+))( *)")
|
|
var returnStatementCompile = makeRegex("( *)(return(( )+" + anyAndNewline + "*)?)( *)")
|
|
var deleteStatmentCompile = makeRegex("( *)(delete( )+" + variableWithIndexes + ")( *)")
|
|
var itemsCompiled = makeRegex("( *)(\\[" + anyAndNewline + "*\\])( *)")
|
|
var breakStatementCompile = makeRegex("( *)break( *)")
|
|
var continueStatementCompile = makeRegex("( *)continue( *)")
|
|
var skipCompile = makeRegex("( *)(#(.*))?")
|
|
var tryCompile = makeRegex("( *)(try( )+\\[" + anyAndNewline + "*)( *)")
|
|
var catchCompile = makeRegex("( *)(\\]( )+catch( )+\\[" + anyAndNewline + "*)( *)")
|
|
var negetiveCompile = makeRegex("( *)(\\-" + anyAndNewline + "+)( *)")
|
|
var processfunc func(codeseg code) (any, bool, any)
|
|
var linefunc func(i int, codearray []code) (any, int, any)
|
|
var opperators = [][]string{
|
|
{
|
|
"&&",
|
|
" and ",
|
|
}, {
|
|
"||",
|
|
" or ",
|
|
}, {
|
|
"!@",
|
|
" not in ",
|
|
" is not in ",
|
|
" isnt in ",
|
|
}, {
|
|
"@",
|
|
" in ",
|
|
" is in ",
|
|
}, {
|
|
"<=",
|
|
" is less than or equal to ",
|
|
" is smaller than or equal to ",
|
|
}, {
|
|
">=",
|
|
" is bigger than or equal to ",
|
|
" is greater than or equal to ",
|
|
" is more than or equal to ",
|
|
}, {
|
|
"<",
|
|
" is less than ",
|
|
" is smaller than ",
|
|
}, {
|
|
">",
|
|
" is bigger than ",
|
|
" is greater than ",
|
|
" is more than ",
|
|
}, {
|
|
"!=",
|
|
" is not ",
|
|
" is not equal to ",
|
|
" isnt equal to ",
|
|
" isnt ",
|
|
"!==",
|
|
}, {
|
|
"==",
|
|
" equals ",
|
|
" is equal to ",
|
|
" is ",
|
|
"===",
|
|
}, {
|
|
" plus ",
|
|
" add ",
|
|
"+",
|
|
}, {
|
|
" minus ",
|
|
" subtract ",
|
|
"-",
|
|
}, {
|
|
"*",
|
|
" x ",
|
|
" times ",
|
|
" multiplied by ",
|
|
}, {
|
|
" mod ",
|
|
" modulo ",
|
|
"%",
|
|
}, {
|
|
" div ",
|
|
" floor division of ",
|
|
" floor divistion ",
|
|
"//",
|
|
"$",
|
|
}, {
|
|
" over ",
|
|
" divided by ",
|
|
"/",
|
|
}, {
|
|
"!**",
|
|
"!^",
|
|
" root ",
|
|
"√",
|
|
}, {
|
|
" to the power of ",
|
|
"^",
|
|
"**",
|
|
}}
|
|
|
|
func opensIndent(str string) bool {
|
|
return tryCompile.MatchString(str) || ifCompile.MatchString(str) || whileCompile.MatchString(str) || subCompile.MatchString(str)
|
|
}
|
|
|
|
func init() {
|
|
processfunc = translateprocess
|
|
linefunc = translateline
|
|
}
|
|
|
|
func getValuesFromCommas(str string, line int) ([]any, bool, any) {
|
|
output := []any{}
|
|
temp := []byte{}
|
|
stringlen := len(str)
|
|
for i := 0; i < stringlen; i++ {
|
|
if str[i] == 44 {
|
|
tempstr := string(temp[:])
|
|
resp, worked, err := processfunc(code{code: tempstr, line: line})
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
if worked {
|
|
output = append(output, resp)
|
|
temp = []byte{}
|
|
continue
|
|
}
|
|
}
|
|
temp = append(temp, str[i])
|
|
}
|
|
tempstr := string(temp[:])
|
|
if tempstr != "" {
|
|
resp, worked, err := processfunc(code{code: tempstr, line: line})
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
if worked {
|
|
output = append(output, resp)
|
|
} else {
|
|
return nil, false, nil
|
|
}
|
|
}
|
|
return output, true, nil
|
|
}
|
|
|
|
// make a function that converts backslashes in a string to their correct character
|
|
// e.g. "\n" -> newline
|
|
// e.g. "\t" -> tab
|
|
// e.g. "\r" -> carriage return
|
|
// e.g. "\b" -> backspace
|
|
// e.g. "\f" -> formfeed
|
|
// e.g. "\a" -> alert
|
|
// e.g. "\v" -> vertical tab
|
|
// e.g. "\0" -> null
|
|
// e.g. "\'" -> single quote
|
|
// e.g. "\"" -> double quote
|
|
// e.g. "\\" -> backslash
|
|
// e.g. unicode characters like \u00A0 -> unicode
|
|
func unescape(str string) string {
|
|
output := []byte{}
|
|
stringlen := len(str)
|
|
for i := 0; i < stringlen; i++ {
|
|
if str[i] == 92 {
|
|
if i+1 < stringlen {
|
|
i++
|
|
switch str[i] {
|
|
case 110:
|
|
output = append(output, 10)
|
|
case 116:
|
|
output = append(output, 9)
|
|
case 114:
|
|
output = append(output, 13)
|
|
case 98:
|
|
output = append(output, 8)
|
|
case 102:
|
|
output = append(output, 12)
|
|
case 118:
|
|
output = append(output, 11)
|
|
case 120:
|
|
output = append(output, 0)
|
|
case 34:
|
|
output = append(output, 34)
|
|
case 39:
|
|
output = append(output, 39)
|
|
case 92:
|
|
output = append(output, 92)
|
|
case 85:
|
|
val, err := strconv.Unquote(`"\U` + str[i+1:i+9] + `"`)
|
|
if err == nil {
|
|
output = append(output, val...)
|
|
i += 8
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
output = append(output, str[i])
|
|
}
|
|
}
|
|
return string(output[:])
|
|
}
|
|
|
|
func getParamNames(str string, line int) ([]string, any) {
|
|
output := []string{}
|
|
temp := []byte{}
|
|
stringlen := len(str)
|
|
for i := 0; i < stringlen; i++ {
|
|
if str[i] == 44 {
|
|
tempstr := strings.Trim(string(temp[:]), " ")
|
|
if !variableonlyCompile.MatchString(tempstr) {
|
|
return nil, ("invalid param name on line" + fmt.Sprint(line+1))
|
|
}
|
|
output = append(output, tempstr)
|
|
temp = []byte{}
|
|
} else {
|
|
temp = append(temp, str[i])
|
|
}
|
|
}
|
|
tempstr := strings.Trim(string(temp[:]), " ")
|
|
if variableonlyCompile.MatchString(tempstr) {
|
|
output = append(output, tempstr)
|
|
}
|
|
return output, nil
|
|
}
|
|
|
|
func split_by_semicolon_and_newline(str string) []code {
|
|
|
|
output := []code{}
|
|
temp := []byte{}
|
|
line := 0
|
|
quote := false
|
|
backtick := false
|
|
speech := false
|
|
str = strings.ReplaceAll(str, "\r", "")
|
|
stringlen := len(str)
|
|
|
|
for i := 0; i < stringlen; i++ {
|
|
if str[i] == 34 && (len(temp) == 0 || str[i-1] != 92) && !speech && !backtick {
|
|
quote = !quote
|
|
} else if str[i] == 96 && (len(temp) == 0 || str[i-1] != 92) && !speech && !quote {
|
|
backtick = !backtick
|
|
} else if str[i] == 39 && (len(temp) == 0 || str[i-1] != 92) && !quote && !backtick {
|
|
speech = !speech
|
|
}
|
|
if (str[i] == 59 && !quote && !speech && !backtick) || (str[i] == 10 && !backtick) {
|
|
output = append(output, code{code: string(temp[:]), line: line})
|
|
if str[i] == 10 {
|
|
line++
|
|
}
|
|
temp = []byte{}
|
|
} else {
|
|
temp = append(temp, str[i])
|
|
}
|
|
}
|
|
output = append(output, code{code: string(temp[:]), line: line})
|
|
return output
|
|
}
|
|
|
|
var getCodeInIndent = func(i int, codearray []code, TYPE string) ([]code, int, any) {
|
|
var result []code
|
|
indent := 0
|
|
start := codearray[i]
|
|
result = append(result, code{
|
|
code: strings.SplitN(codearray[i].code, "[", 2)[1],
|
|
line: codearray[i].line,
|
|
})
|
|
i++
|
|
for {
|
|
if i == len(codearray) {
|
|
return nil, 0, ("invalid opening brackets starting on line " + fmt.Sprint(start.line+1) + ": " + start.code)
|
|
}
|
|
if (TYPE != "try" && closeCompile.MatchString(codearray[i].code) && !setVariableCompile.MatchString(codearray[i].code) && !switchCloseCompile.MatchString(codearray[i].code)) || (TYPE == "if" && (elseCompile.MatchString(codearray[i].code) || elseifCompile.MatchString(codearray[i].code)) || (TYPE == "try" && catchCompile.MatchString(codearray[i].code))) {
|
|
indent--
|
|
if indent < 0 {
|
|
break
|
|
}
|
|
} else if opensIndent(codearray[i].code) {
|
|
indent++
|
|
}
|
|
result = append(result, codearray[i])
|
|
i++
|
|
}
|
|
i++
|
|
return result, i, nil
|
|
}
|
|
|
|
var translateprocess = func(codeseg code) (any, bool, any) {
|
|
for i := 0; i < len(opperators); i++ {
|
|
for j := 0; j < len(opperators[i]); j++ {
|
|
split := strings.Split(codeseg.code, opperators[i][j])
|
|
if len(split) > 1 {
|
|
vals := []any{}
|
|
current := 0
|
|
for k := 0; k < len(split); k++ {
|
|
currentstr := strings.Join(split[current:k], opperators[i][j])
|
|
val, worked, _ := processfunc(code{
|
|
code: currentstr,
|
|
line: codeseg.line,
|
|
})
|
|
if worked {
|
|
vals = append(vals, val)
|
|
current = k
|
|
}
|
|
}
|
|
if len(vals) >= 1 {
|
|
currentstr := strings.Join(split[current:], opperators[i][j])
|
|
val, worked, err := processfunc(code{
|
|
code: currentstr,
|
|
line: codeseg.line,
|
|
})
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
if worked {
|
|
vals = append(vals, val)
|
|
|
|
return opperator{
|
|
t: i,
|
|
vals: vals,
|
|
line: codeseg.line,
|
|
}, true, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if stringCompile.MatchString(codeseg.code) {
|
|
return unescape(stringencode(codeseg.code)), true, nil
|
|
} else if negetiveCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
val, worked, err := processfunc(code{
|
|
code: str[1:],
|
|
line: codeseg.line,
|
|
})
|
|
if err != nil {
|
|
return val, worked, err
|
|
}
|
|
if !worked {
|
|
return nil, false, "invalid value on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
return opperator{
|
|
t: 11,
|
|
vals: []any{0, val},
|
|
line: codeseg.line,
|
|
}, true, nil
|
|
} else if functionCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
indent := 0
|
|
output := []byte{}
|
|
for i := len(str) - 2; i >= 0; i-- {
|
|
if str[i] == ')' {
|
|
indent++
|
|
} else if str[i] == '(' {
|
|
indent--
|
|
if indent < 0 {
|
|
break
|
|
}
|
|
}
|
|
output = append([]byte{str[i]}, output...)
|
|
}
|
|
params := string(output[:])
|
|
paramstranslated, worked, err := getValuesFromCommas(params, codeseg.line)
|
|
if !worked {
|
|
return nil, false, "invalid params on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
FUNC, worked, err := processfunc(code{
|
|
code: str[:len(str)-len(params)-2],
|
|
line: codeseg.line,
|
|
})
|
|
if !worked {
|
|
return nil, false, "invalid value on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
if worked {
|
|
return funcCallType{
|
|
FUNC: FUNC,
|
|
args: paramstranslated,
|
|
line: codeseg.line,
|
|
}, true, nil
|
|
}
|
|
} else if bracketsCompile.MatchString(codeseg.code) {
|
|
shorter := strings.Trim(codeseg.code, " ")
|
|
shorter = shorter[1 : len(shorter)-1]
|
|
brackets, ran, err := processfunc(code{
|
|
code: shorter,
|
|
line: codeseg.line,
|
|
})
|
|
return brackets, ran, err
|
|
} else if itemsCompiled.MatchString(codeseg.code) {
|
|
inside := strings.Trim(codeseg.code, " ")[1 : len(strings.Trim(codeseg.code, " "))-1]
|
|
vals, worked, err := getValuesFromCommas(inside, codeseg.line)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
if worked {
|
|
return itemsType{
|
|
vals: vals,
|
|
line: codeseg.line,
|
|
}, true, nil
|
|
}
|
|
} else if indexCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
indent := 0
|
|
output := []byte{}
|
|
for i := len(str) - 2; i >= 0; i-- {
|
|
if str[i] == ']' {
|
|
indent++
|
|
} else if str[i] == '[' {
|
|
indent--
|
|
if indent < 0 {
|
|
break
|
|
}
|
|
}
|
|
output = append([]byte{str[i]}, output...)
|
|
}
|
|
value := string(output[:])
|
|
resp, worked, err := processfunc(code{
|
|
code: value,
|
|
line: codeseg.line,
|
|
})
|
|
if !worked {
|
|
return nil, false, "invalid index value on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
index := resp
|
|
|
|
resp, worked, err = processfunc(code{
|
|
code: str[:len(str)-len(value)-2],
|
|
line: codeseg.line,
|
|
})
|
|
if !worked {
|
|
return nil, false, "invalid value on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
return indexType{
|
|
to: resp,
|
|
index: index,
|
|
line: codeseg.line,
|
|
}, true, nil
|
|
} else if numberCompile.MatchString(codeseg.code) {
|
|
if s, err := strconv.ParseFloat(strings.Trim(codeseg.code, " "), 64); err == nil {
|
|
return s, true, nil
|
|
} else {
|
|
return nil, false, err
|
|
}
|
|
} else if variableTextCompile.MatchString(codeseg.code) {
|
|
return variable{
|
|
variable: strings.Trim(codeseg.code, " "),
|
|
line: codeseg.line,
|
|
}, true, nil
|
|
}
|
|
return nil, false, nil
|
|
}
|
|
|
|
var translateline = func(i int, codearray []code) (any, int, any) {
|
|
codeseg := codearray[i]
|
|
if returnStatementCompile.MatchString(codeseg.code) {
|
|
var val any = strings.Trim(codeseg.code, " ")[6:]
|
|
if val != "" {
|
|
respval, worked, err := translateprocess(code{code: val.(string), line: codeseg.line})
|
|
if !worked || err != nil {
|
|
return nil, 0, ("invalid value on line " + fmt.Sprint(codeseg.line+1))
|
|
}
|
|
val = respval
|
|
} else {
|
|
val = nil
|
|
}
|
|
return returnType{
|
|
val: val,
|
|
line: codeseg.line,
|
|
}, i + 1, nil
|
|
} else if breakStatementCompile.MatchString(codeseg.code) {
|
|
return breakType{
|
|
line: codeseg.line,
|
|
}, i + 1, nil
|
|
} else if continueStatementCompile.MatchString(codeseg.code) {
|
|
return continueType{
|
|
line: codeseg.line,
|
|
}, i + 1, nil
|
|
} else if skipCompile.MatchString(codeseg.code) {
|
|
return nil, i + 1, nil
|
|
} else if setVariableCompile.MatchString(codeseg.code) {
|
|
VAR := strings.Split(codeseg.code, "=")
|
|
firstSplit := strings.Split(strings.Trim(VAR[0], " "), " ")
|
|
TYPE := "preset"
|
|
if len(firstSplit) > 1 {
|
|
TYPE = firstSplit[0]
|
|
}
|
|
vari := firstSplit[len(firstSplit)-1]
|
|
resp, worked, err := translateprocess(code{code: VAR[1],
|
|
line: codeseg.line})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if !worked {
|
|
return nil, 0, ("invalid value on line " + fmt.Sprint(codeseg.line+1) + ": " + VAR[1])
|
|
}
|
|
return setVariable{
|
|
TYPE: TYPE,
|
|
variable: variable{
|
|
variable: vari,
|
|
line: codeseg.line,
|
|
},
|
|
value: resp,
|
|
line: codeseg.line,
|
|
}, i + 1, nil
|
|
}
|
|
resp, worked, err := translateprocess(codeseg)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if worked {
|
|
return resp, i + 1, nil
|
|
} else if deleteStatmentCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
return deleteType{
|
|
variable: variable{
|
|
variable: str[7:],
|
|
line: codeseg.line,
|
|
},
|
|
line: codeseg.line,
|
|
}, i + 1, nil
|
|
} else if whileCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
strlen := len(str)
|
|
str = str[5:strlen]
|
|
split := strings.SplitN(str, "[", 2)
|
|
condition, worked, err := translateprocess(code{code: split[0],
|
|
line: codeseg.line})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if !worked {
|
|
return nil, 0, ("invalid value on line " + fmt.Sprint(codeseg.line+1))
|
|
}
|
|
codedata, x, err := getCodeInIndent(i, codearray, "none")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
codeoutput := []any{}
|
|
|
|
codelen := len(codedata)
|
|
for i := 0; i < codelen; {
|
|
resp, x, err := linefunc(i, codedata)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
i = x
|
|
|
|
if resp != nil {
|
|
codeoutput = append(codeoutput, resp)
|
|
}
|
|
}
|
|
|
|
return whileLoop{
|
|
condition: condition,
|
|
code: codeoutput,
|
|
}, x, nil
|
|
} else if tryCompile.MatchString(codeseg.code) {
|
|
codedata, x, err := getCodeInIndent(i, codearray, "try")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
codeoutput := []any{}
|
|
|
|
codelen := len(codedata)
|
|
for i := 0; i < codelen; {
|
|
resp, x, err := linefunc(i, codedata)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
i = x
|
|
|
|
if resp != nil {
|
|
codeoutput = append(codeoutput, resp)
|
|
}
|
|
}
|
|
catchdata, x, err := getCodeInIndent(x-1, codearray, "none")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
catchoutput := []any{}
|
|
catchlen := len(catchdata)
|
|
for i := 0; i < catchlen; {
|
|
resp, x, err := linefunc(i, catchdata)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
i = x
|
|
|
|
if resp != nil {
|
|
catchoutput = append(catchoutput, resp)
|
|
}
|
|
}
|
|
return tryType{
|
|
code: codeoutput,
|
|
catch: catchoutput,
|
|
line: codeseg.line,
|
|
}, x, nil
|
|
} else if ifCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
strlen := len(str)
|
|
str = str[2:strlen]
|
|
split := strings.SplitN(str, "[", 2)
|
|
condition, worked, err := translateprocess(code{code: split[0],
|
|
line: codeseg.line})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if !worked {
|
|
return nil, 0, ("invalid value on line " + fmt.Sprint(codeseg.line+1) + ": " + split[0])
|
|
}
|
|
codedata, x, err := getCodeInIndent(i, codearray, "if")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
codeoutput := []any{}
|
|
|
|
codelen := len(codedata)
|
|
for i := 0; i < codelen; {
|
|
resp, x, err := linefunc(i, codedata)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
i = x
|
|
if resp != nil {
|
|
codeoutput = append(codeoutput, resp)
|
|
}
|
|
}
|
|
ifstatementcode := []iftype{
|
|
{
|
|
condition: condition,
|
|
code: codeoutput,
|
|
},
|
|
}
|
|
elsecode := []any{}
|
|
for {
|
|
if elseifCompile.MatchString(codearray[x-1].code) {
|
|
str := strings.Trim(codearray[x-1].code, " ")
|
|
str = strings.SplitN(str[1:len(str)-1], "if", 2)[1]
|
|
condition, worked, err = translateprocess(code{code: str,
|
|
line: codearray[x-1].line})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if !worked {
|
|
return nil, 0, "invalid value on line " + fmt.Sprint(codearray[x-1].line+1) + ": " + split[0]
|
|
}
|
|
codedata, j, err := getCodeInIndent(x-1, codearray, "if")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
codeoutput := []any{}
|
|
x = j
|
|
codelen := len(codedata)
|
|
for i := 0; i < codelen; {
|
|
resp, x, err := linefunc(i, codedata)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
i = x
|
|
if resp != nil {
|
|
codeoutput = append(codeoutput, resp)
|
|
}
|
|
}
|
|
ifstatementcode = append(ifstatementcode,
|
|
iftype{
|
|
condition: condition,
|
|
code: codeoutput,
|
|
})
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
if elseCompile.MatchString(codearray[x-1].code) {
|
|
codedata, j, err := getCodeInIndent(x-1, codearray, "none")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
x += j - 3
|
|
codelen := len(codedata)
|
|
for i := 0; i < codelen; {
|
|
resp, x, err := linefunc(i, codedata)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
i = x
|
|
if resp != nil {
|
|
elsecode = append(elsecode, resp)
|
|
}
|
|
}
|
|
}
|
|
return ifstatement{
|
|
statments: ifstatementcode,
|
|
FALSE: elsecode,
|
|
}, x, nil
|
|
} else if subCompile.MatchString(codeseg.code) {
|
|
sub := strings.Trim(codeseg.code, " ")
|
|
sub = sub[4:]
|
|
split := strings.SplitN(sub, "[", 2)
|
|
functioninfo := strings.SplitN(strings.Trim(split[0], " "), "(", 2)
|
|
functionname := functioninfo[0]
|
|
argstr := functioninfo[1]
|
|
argstr = argstr[:len(argstr)-1]
|
|
args, err := getParamNames(argstr, codeseg.line)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
codedata, x, err := getCodeInIndent(i, codearray, "none")
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
codeoutput := []any{}
|
|
|
|
codelen := len(codedata)
|
|
for i := 0; i < codelen; {
|
|
resp, x, err := linefunc(i, codedata)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
i = x
|
|
if resp != nil {
|
|
codeoutput = append(codeoutput, resp)
|
|
}
|
|
}
|
|
return setFunction{
|
|
name: functionname,
|
|
FUNC: callableFunction{
|
|
name: functionname,
|
|
args: args,
|
|
code: codeoutput,
|
|
line: codeseg.line,
|
|
},
|
|
line: codeseg.line,
|
|
}, x, nil
|
|
} else if importCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
var toImport any = nil
|
|
var path any
|
|
if strings.HasPrefix(str, "import") {
|
|
if variableonlyCompile.MatchString(strings.Trim(str[7:], " ")) {
|
|
path = strings.Trim(str[7:], " ")
|
|
} else {
|
|
p, worked, err := processfunc(code{code: str[7:], line: codeseg.line})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
path = p
|
|
if !worked {
|
|
return nil, 0, "invalid import path on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
}
|
|
} else {
|
|
info := strings.SplitN(str[5:], " import ", 2)
|
|
if variableonlyCompile.MatchString(strings.Trim(info[0], " ")) {
|
|
path = strings.Trim(info[0], " ")
|
|
} else {
|
|
p, worked, err := processfunc(code{code: info[0], line: codeseg.line})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
path = p
|
|
if !worked {
|
|
return nil, 0, "invalid import path on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
}
|
|
toImport, err = getParamNames(info[1], codeseg.line)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
}
|
|
return importType{
|
|
path: path,
|
|
toImport: toImport,
|
|
line: codeseg.line,
|
|
}, i + 1, nil
|
|
} else if callErrorCompile.MatchString(codeseg.code) {
|
|
str := strings.Trim(codeseg.code, " ")
|
|
val, worked, err := processfunc(code{code: str[6:], line: codeseg.line})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if worked {
|
|
return errorType{
|
|
val,
|
|
}, i + 1, nil
|
|
} else {
|
|
return nil, 0, "invalid error value on line " + fmt.Sprint(codeseg.line+1)
|
|
}
|
|
} else {
|
|
err := "Invalid syntax on line "
|
|
return nil, 0, ("\n\nLine " + fmt.Sprint(codeseg.line+1) + ": " + codeseg.code + "\n" + err + "\n\n")
|
|
}
|
|
}
|
|
|
|
var translate = func(str string) ([]any, any) {
|
|
code := split_by_semicolon_and_newline(str)
|
|
codelen := len(code)
|
|
output := []any{}
|
|
i := 0
|
|
for i < codelen {
|
|
resp, x, err := translateline(i, code)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
i = x
|
|
if resp != nil {
|
|
output = append(output, resp)
|
|
}
|
|
}
|
|
return output, nil
|
|
}
|