mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 00:46:07 +00:00
start working on opperations
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var bracketsCompile = makeRegex(`( *)\((.|\n)+\)( *)`)
|
||||
|
||||
@@ -17,7 +19,7 @@ func isBrackets(code UNPARSEcode) bool {
|
||||
|
||||
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],
|
||||
code: strings.TrimSpace(code.code)[1 : len(code.code)-2],
|
||||
realcode: code.realcode,
|
||||
line: code.line,
|
||||
path: code.path,
|
||||
|
||||
@@ -84,7 +84,8 @@ func runCall(c call, stack stack) (any, ArErr) {
|
||||
for i, param := range x.params {
|
||||
level[param] = args[i]
|
||||
}
|
||||
return runVal(x.run, append(stack, level))
|
||||
resp, err := runVal(x.run, append(stack, level))
|
||||
return resp, err
|
||||
}
|
||||
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,13 @@ func mapGet(r ArMapGet, stack stack) (any, ArErr) {
|
||||
}
|
||||
}
|
||||
|
||||
func classVal(r any) any {
|
||||
if _, ok := r.(ArClass); ok {
|
||||
return r.(ArClass).value
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func isMapGet(code UNPARSEcode) bool {
|
||||
return mapGetCompile.MatchString(code.code)
|
||||
}
|
||||
@@ -81,6 +88,6 @@ func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet
|
||||
if !worked {
|
||||
return ArMapGet{}, false, err, i
|
||||
}
|
||||
k := translateString{key, code.realcode, code.line}
|
||||
k := key
|
||||
return ArMapGet{resp, k, code.line, code.realcode, code.path}, true, ArErr{}, 1
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ func isNumber(code UNPARSEcode) bool {
|
||||
return numberCompile.MatchString(code.code) || binaryCompile.MatchString(code.code) || hexCompile.MatchString(code.code) || octalCompile.MatchString(code.code)
|
||||
}
|
||||
|
||||
func isAnyNumber(x any) bool {
|
||||
_, ok := x.(number)
|
||||
return ok
|
||||
}
|
||||
|
||||
// converts a number type to a string
|
||||
func numberToString(num number, fraction int) string {
|
||||
if fraction != 0 {
|
||||
@@ -44,7 +49,7 @@ func numberToString(num number, fraction int) string {
|
||||
denominator := split[1]
|
||||
|
||||
super := []string{}
|
||||
for i := 0; i < len(numerator); i++ {
|
||||
for i := 0; i <= len(numerator); i++ {
|
||||
super = append(super, superscript[numerator[i]])
|
||||
}
|
||||
sub := []string{}
|
||||
|
||||
138
src/operations.go
Normal file
138
src/operations.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var operations = [][]string{
|
||||
{"-"},
|
||||
{"+"},
|
||||
{"/"},
|
||||
{"*"},
|
||||
{"%"},
|
||||
{"**", "^"},
|
||||
{"=="},
|
||||
{"!=", "≠"},
|
||||
{"<=", "≤"},
|
||||
{">=", "≥"},
|
||||
{"<"},
|
||||
{">"},
|
||||
{"&&", " and "},
|
||||
{"||", " or "},
|
||||
}
|
||||
|
||||
type operationType struct {
|
||||
operation int
|
||||
values []any
|
||||
line int
|
||||
code string
|
||||
path string
|
||||
}
|
||||
|
||||
func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (operationType, bool, ArErr, int) {
|
||||
for i := 0; i < len(operations); i++ {
|
||||
values := []any{}
|
||||
current := 0
|
||||
for l := 0; l < len(code.code); l++ {
|
||||
for j := 0; j < len(operations[i]); j++ {
|
||||
if len(code.code[l:]) >= len(operations[i][j]) && code.code[l:l+len(operations[i][j])] == operations[i][j] {
|
||||
|
||||
resp, success, _, respindex := translateVal(
|
||||
UNPARSEcode{
|
||||
code: code.code[current:l],
|
||||
realcode: code.realcode,
|
||||
line: code.line,
|
||||
path: code.path,
|
||||
}, index, codelines, false)
|
||||
|
||||
if success {
|
||||
index += respindex - 1
|
||||
values = append(values, resp)
|
||||
current = l + len(operations[i][j])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(values) > 0 {
|
||||
resp, success, err, respindex := translateVal(
|
||||
UNPARSEcode{
|
||||
code: code.code[current:],
|
||||
realcode: code.realcode,
|
||||
line: code.line,
|
||||
path: code.path,
|
||||
}, index, codelines, false)
|
||||
if success {
|
||||
index += respindex - 1
|
||||
values = append(values, resp)
|
||||
return operationType{
|
||||
i,
|
||||
values,
|
||||
code.line,
|
||||
code.realcode,
|
||||
code.path,
|
||||
}, true, err, index
|
||||
}
|
||||
return operationType{}, false, err, index
|
||||
}
|
||||
}
|
||||
return operationType{}, false, ArErr{}, index
|
||||
}
|
||||
|
||||
func calcNegative(o operationType, stack stack) (number, ArErr) {
|
||||
|
||||
resp, err := runVal(
|
||||
o.values[0],
|
||||
stack,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if !isAnyNumber(resp) {
|
||||
return nil, ArErr{
|
||||
"Runtime Error",
|
||||
"Cannot subtract from type '" + typeof(resp) + "'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
}
|
||||
}
|
||||
output := resp.(number)
|
||||
for i := 1; i < len(o.values); i++ {
|
||||
resp, err := runVal(
|
||||
o.values[i],
|
||||
stack,
|
||||
)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
if isAnyNumber(resp) {
|
||||
output = output.Sub(output, resp.(number))
|
||||
} else {
|
||||
return nil, ArErr{
|
||||
"Runtime Error",
|
||||
"Cannot subtract type '" + typeof(resp) + "'",
|
||||
o.line,
|
||||
o.path,
|
||||
o.code,
|
||||
true,
|
||||
}
|
||||
}
|
||||
}
|
||||
return output, ArErr{}
|
||||
}
|
||||
|
||||
func runOperation(o operationType, stack stack) (any, ArErr) {
|
||||
switch o.operation {
|
||||
case 0:
|
||||
resp, err := calcNegative(o, stack)
|
||||
if err.EXISTS {
|
||||
return resp, err
|
||||
}
|
||||
return resp, ArErr{}
|
||||
|
||||
}
|
||||
panic("Unknown operation: " + fmt.Sprint(o.operation))
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// returns (number|string|nil), error
|
||||
func runVal(line any, stack stack) (any, ArErr) {
|
||||
if len(stack) > 500 {
|
||||
@@ -26,6 +31,7 @@ func runVal(line any, stack stack) (any, ArErr) {
|
||||
return setVariableValue(x, stack)
|
||||
case negative:
|
||||
resp, err := runVal(x.VAL, stack)
|
||||
resp = classVal(resp)
|
||||
if err.EXISTS {
|
||||
return nil, err
|
||||
}
|
||||
@@ -40,7 +46,10 @@ func runVal(line any, stack stack) (any, ArErr) {
|
||||
}
|
||||
case brackets:
|
||||
return runVal(x.VAL, stack)
|
||||
case operationType:
|
||||
return runOperation(x, stack)
|
||||
}
|
||||
fmt.Println("unreachable", reflect.TypeOf(line))
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type translateString struct {
|
||||
str string
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
var stringCompile = makeRegex("(( *)\"((\\\\([a-z\\\"'`]))|[^\\\"])*\"( *))|(( *)'((\\\\([a-z\\'\"`]))|[^\\'])*'( *))")
|
||||
|
||||
func isString(code UNPARSEcode) bool {
|
||||
|
||||
@@ -7,7 +7,7 @@ type UNPARSEcode struct {
|
||||
path string
|
||||
}
|
||||
|
||||
// returns (translateNumber | translateString| nil), success, error, step
|
||||
// returns (number | string | nil), success, error, step
|
||||
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine bool) (any, bool, ArErr, int) {
|
||||
if isLine {
|
||||
if isBlank(code) {
|
||||
@@ -19,11 +19,18 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine b
|
||||
}
|
||||
}
|
||||
}
|
||||
if isSetVariable(code) {
|
||||
return parseSetVariable(code, index, codelines)
|
||||
} else if isBrackets(code) {
|
||||
if isBrackets(code) {
|
||||
return parseBrackets(code, index, codelines)
|
||||
} else if isNumber(code) {
|
||||
} else if isSetVariable(code) {
|
||||
return parseSetVariable(code, index, codelines)
|
||||
}
|
||||
operation, worked, err, step := parseOperations(code, index, codelines)
|
||||
if worked {
|
||||
return operation, worked, err, step
|
||||
} else if err.EXISTS {
|
||||
return nil, worked, err, step
|
||||
}
|
||||
if isNumber(code) {
|
||||
return parseNumber(code)
|
||||
} else if isNegative(code) {
|
||||
return parseNegative(code, index, codelines)
|
||||
@@ -39,7 +46,7 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine b
|
||||
return nil, false, ArErr{"Syntax Error", "invalid syntax", code.line, code.path, code.realcode, true}, 1
|
||||
}
|
||||
|
||||
// returns [](translateNumber | translateString), error
|
||||
// returns [](number | string), error
|
||||
func translate(codelines []UNPARSEcode) ([]any, ArErr) {
|
||||
translated := []any{}
|
||||
for i := 0; i < len(codelines); {
|
||||
|
||||
@@ -116,7 +116,7 @@ func setVariableValue(v setVariable, stack stack) (any, ArErr) {
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
if _, ok := stack[i][v.name]; ok {
|
||||
stack[i][v.name] = resp
|
||||
return stack, ArErr{}
|
||||
return resp, ArErr{}
|
||||
}
|
||||
}
|
||||
stack[len(stack)-1][v.name] = resp
|
||||
|
||||
Reference in New Issue
Block a user