From 035df8075843dc315908f16e499fa7021baf3ad7 Mon Sep 17 00:00:00 2001 From: William Bell Date: Sun, 6 Aug 2023 18:23:35 +0100 Subject: [PATCH] fix variable unable to be assigned on the same line --- .vscode/settings.json | 5 --- argon-package.json | 2 +- src/arvalid.go | 17 ++++++++ src/built-ins.go | 25 +---------- src/main.go | 2 +- src/translate.go | 66 +++++++++-------------------- src/variable.go | 96 +++++++++++++++++++++++++++++++------------ 7 files changed, 108 insertions(+), 105 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 5d25211..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files.associations": { - "*.ar": "lua" - } -} diff --git a/argon-package.json b/argon-package.json index 92bf556..91a92ea 100644 --- a/argon-package.json +++ b/argon-package.json @@ -1,4 +1,4 @@ { "name": "argon-v3", - "version": "1.0.0" + "version": "3.0.1" } \ No newline at end of file diff --git a/src/arvalid.go b/src/arvalid.go index c349bb1..fc78226 100644 --- a/src/arvalid.go +++ b/src/arvalid.go @@ -26,3 +26,20 @@ func ArValidToAny(a any) any { } return a } + +func ArValidToHash(a any) (any, ArErr) { + switch a := a.(type) { + case ArObject: + if callable, ok := a.obj["__hash__"]; ok { + value, err := runCall(call{ + Callable: callable, + Args: []any{}, + }, stack{}, 0) + if err.EXISTS { + return nil, err + } + return value, ArErr{} + } + } + return a, ArErr{} +} diff --git a/src/built-ins.go b/src/built-ins.go index 61a1353..a24d532 100644 --- a/src/built-ins.go +++ b/src/built-ins.go @@ -224,7 +224,7 @@ func makeGlobal() ArObject { }} vars["subprocess"] = builtinFunc{"subprocess", ArSubprocess} vars["sequence"] = builtinFunc{"sequence", ArSequence} - vars["exit"] = builtinFunc{"exit", func(a ...any) (any, ArErr) { + vars["|"] = builtinFunc{"exit", func(a ...any) (any, ArErr) { if len(a) == 0 { os.Exit(0) } @@ -235,29 +235,6 @@ func makeGlobal() ArObject { os.Exit(0) return nil, ArErr{} }} - vars["error"] = builtinFunc{"error", func(a ...any) (any, ArErr) { - if len(a) < 1 || len(a) > 2 { - return nil, ArErr{TYPE: "error", message: "error takes 1 or 2 arguments, got " + fmt.Sprint(len(a)), EXISTS: true} - } - if len(a) == 1 { - a[0] = ArValidToAny(a[0]) - switch x := a[0].(type) { - case string: - return nil, ArErr{TYPE: "Error", message: x, EXISTS: true} - } - } else { - a[0] = ArValidToAny(a[0]) - a[1] = ArValidToAny(a[1]) - switch x := a[0].(type) { - case string: - switch y := a[1].(type) { - case string: - return nil, ArErr{TYPE: x, message: y, EXISTS: true} - } - } - } - return nil, ArErr{TYPE: "TypeError", message: "Cannot create error from '" + typeof(a[0]) + "'", EXISTS: true} - }} vars["chr"] = builtinFunc{"chr", func(a ...any) (any, ArErr) { if len(a) != 1 { return nil, ArErr{TYPE: "chr", message: "chr takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true} diff --git a/src/main.go b/src/main.go index 686c723..b023f9a 100644 --- a/src/main.go +++ b/src/main.go @@ -10,7 +10,7 @@ var Args = os.Args[1:] type stack = []ArObject -const VERSION = "3.0.0" +const VERSION = "3.0.1" // Example struct type Person struct { diff --git a/src/translate.go b/src/translate.go index d67ff31..d608ff3 100644 --- a/src/translate.go +++ b/src/translate.go @@ -11,21 +11,10 @@ type UNPARSEcode struct { path string } -var knownFailures = []string{} -var knownFailuresErrs = []ArErr{} - -func StringExists(arr []string, target string) (bool, ArErr) { - for i, str := range arr { - if str == target { - return true, knownFailuresErrs[i] - } - } - return false, ArErr{} -} +var knownFailures = map[string]ArErr{} func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine int) (any, bool, ArErr, int) { - known, knownErr := StringExists(knownFailures, code.code) - if known { + if knownErr, ok := knownFailures[code.code]; ok { return nil, false, ArErr{ knownErr.TYPE, knownErr.message, @@ -45,8 +34,7 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i if isDeleteVariable(code) { resp, worked, err, i = parseDelete(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isComment(code) { @@ -57,64 +45,55 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i } else if isReturn(code) { resp, worked, err, i = parseReturn(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isBreak(code) { resp, worked, err, i = parseBreak(code) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isContinue(code) { resp, worked, err, i = parseContinue(code) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isIfStatement(code) { resp, worked, err, i = parseIfStatement(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isWhileLoop(code) { resp, worked, err, i = parseWhileLoop(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isForeverLoop(code) { resp, worked, err, i = parseForeverLoop(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isForLoop(code) { resp, worked, err, i = parseForLoop(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isGenericImport(code) { resp, worked, err, i = parseGenericImport(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isTryCatch(code) { resp, worked, err, i = parseTryCatch(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } @@ -124,8 +103,7 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i if isDoWrap(code) { resp, worked, err, i = parseDoWrap(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } @@ -164,15 +142,13 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i if isNumber(code) { resp, worked, err, i = parseNumber(code) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isString(code) { resp, worked, err, i = parseString(code) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if issquareroot(code) { @@ -190,8 +166,7 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i if isVariable(code) { resp, worked, err, i = parseVariable(code) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } @@ -226,15 +201,13 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i if isNegative(code) { resp, worked, err, i = parseNegative(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isMapGet(code) { resp, worked, err, i = mapGetParse(code, index, codelines) if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } else if isIndexGet(code) { @@ -244,8 +217,7 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i } } if !worked { - knownFailures = append(knownFailures, code.code) - knownFailuresErrs = append(knownFailuresErrs, err) + knownFailures[code.code] = err } return resp, worked, err, i } diff --git a/src/variable.go b/src/variable.go index f30b828..1919c89 100644 --- a/src/variable.go +++ b/src/variable.go @@ -171,36 +171,78 @@ func parseSetVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine i return setVariable{TYPE: "let", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1 } +var operationsToInt = map[byte]int{ + '+': 10, + '-': 11, + '*': 12, + '/': 15, + '^': 16, + '&': 0, + '|': 1, +} + func parseAutoAsignVariable(code UNPARSEcode, index int, lines []UNPARSEcode, isLine int) (setVariable, bool, ArErr, int) { trim := strings.TrimSpace(code.code) - equalsplit := strings.SplitN(trim, "=", 2) - name := strings.TrimSpace(equalsplit[0]) - params := []string{} - function := false - if blockedVariableNames[name] { - return setVariable{}, false, ArErr{"Naming Error", "\"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1 + equalsplit := strings.Split(trim, "=") + for i := 1; i < len(equalsplit); i++ { + name := strings.TrimSpace(strings.Join(equalsplit[:i], "=")) + if name == "" { + continue + } + operation := name[len(name)-1] + var operationtype int = -1 + if operation == '+' || operation == '-' || operation == '*' || operation == '/' || operation == '^' || operation == '&' || operation == '|' { + name = strings.TrimSpace(name[:len(name)-1]) + if n, ok := operationsToInt[operation]; ok { + operationtype = n + } + } + params := []string{} + function := false + if blockedVariableNames[name] { + if i == len(equalsplit)-1 { + return setVariable{}, false, ArErr{"Naming Error", "\"" + name + "\" is a reserved keyword", code.line, code.path, code.realcode, true}, 1 + } + continue + } + toset, success, err, namei := nameToTranslated(UNPARSEcode{code: name, realcode: code.realcode, line: code.line, path: code.path}, index, lines) + if err.EXISTS { + if i == len(equalsplit)-1 { + return setVariable{}, success, err, namei + } + continue + } + switch x := toset.(type) { + case accessVariable: + break + case ArMapGet: + break + case setFunction: + function = true + params = x.params + toset = x.toset + default: + if i == len(equalsplit)-1 { + return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean to put 'let' before?", code.line, code.path, code.realcode, true}, 1 + } + continue + } + value, success, err, i := translateVal(UNPARSEcode{code: strings.Join(equalsplit[i:], "="), realcode: code.realcode, line: code.line, path: code.path}, index, lines, isLine) + if !success { + return setVariable{}, false, err, i + } + if operationtype != -1 { + value = operationType{ + operation: operationtype, + values: []any{toset, value}, + line: code.line, + code: code.code, + path: code.path, + } + } + return setVariable{TYPE: "auto", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1 } - toset, success, err, namei := nameToTranslated(UNPARSEcode{code: name, realcode: code.realcode, line: code.line, path: code.path}, index, lines) - if err.EXISTS { - return setVariable{}, success, err, namei - } - switch x := toset.(type) { - case accessVariable: - break - case ArMapGet: - break - case setFunction: - function = true - params = x.params - toset = x.toset - default: - return setVariable{}, false, ArErr{"Type Error", "can't set for non variable, did you mean '=='?", 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, isLine) - if !success { - return setVariable{}, false, err, i - } - return setVariable{TYPE: "auto", toset: toset, value: value, function: function, params: params, line: code.line, code: code.code, path: code.path}, true, ArErr{}, i + namei - 1 + return setVariable{}, false, ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true}, 1 } func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {