start working on opperations

This commit is contained in:
2023-03-07 18:27:06 +00:00
parent 1b3a4c44d9
commit dfb93c60b4
11 changed files with 185 additions and 21 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1,6 +1,8 @@
package main package main
import "strings" import (
"strings"
)
var bracketsCompile = makeRegex(`( *)\((.|\n)+\)( *)`) 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) { func parseBrackets(code UNPARSEcode, index int, codeline []UNPARSEcode) (brackets, bool, ArErr, int) {
resp, worked, err, i := translateVal(UNPARSEcode{ 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, realcode: code.realcode,
line: code.line, line: code.line,
path: code.path, path: code.path,

View File

@@ -84,7 +84,8 @@ func runCall(c call, stack stack) (any, ArErr) {
for i, param := range x.params { for i, param := range x.params {
level[param] = args[i] 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} return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
} }

View File

@@ -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 { func isMapGet(code UNPARSEcode) bool {
return mapGetCompile.MatchString(code.code) return mapGetCompile.MatchString(code.code)
} }
@@ -81,6 +88,6 @@ func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet
if !worked { if !worked {
return ArMapGet{}, false, err, i 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 return ArMapGet{resp, k, code.line, code.realcode, code.path}, true, ArErr{}, 1
} }

View File

@@ -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) 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 // converts a number type to a string
func numberToString(num number, fraction int) string { func numberToString(num number, fraction int) string {
if fraction != 0 { if fraction != 0 {
@@ -44,7 +49,7 @@ func numberToString(num number, fraction int) string {
denominator := split[1] denominator := split[1]
super := []string{} super := []string{}
for i := 0; i < len(numerator); i++ { for i := 0; i <= len(numerator); i++ {
super = append(super, superscript[numerator[i]]) super = append(super, superscript[numerator[i]])
} }
sub := []string{} sub := []string{}

138
src/operations.go Normal file
View 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))
}

View File

@@ -1,5 +1,10 @@
package main package main
import (
"fmt"
"reflect"
)
// 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 { if len(stack) > 500 {
@@ -26,6 +31,7 @@ func runVal(line any, stack stack) (any, ArErr) {
return setVariableValue(x, stack) return setVariableValue(x, stack)
case negative: case negative:
resp, err := runVal(x.VAL, stack) resp, err := runVal(x.VAL, stack)
resp = classVal(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -40,7 +46,10 @@ func runVal(line any, stack stack) (any, ArErr) {
} }
case brackets: case brackets:
return runVal(x.VAL, stack) return runVal(x.VAL, stack)
case operationType:
return runOperation(x, stack)
} }
fmt.Println("unreachable", reflect.TypeOf(line))
panic("unreachable") panic("unreachable")
} }

View File

@@ -5,12 +5,6 @@ import (
"strings" "strings"
) )
type translateString struct {
str string
code string
line int
}
var stringCompile = makeRegex("(( *)\"((\\\\([a-z\\\"'`]))|[^\\\"])*\"( *))|(( *)'((\\\\([a-z\\'\"`]))|[^\\'])*'( *))") var stringCompile = makeRegex("(( *)\"((\\\\([a-z\\\"'`]))|[^\\\"])*\"( *))|(( *)'((\\\\([a-z\\'\"`]))|[^\\'])*'( *))")
func isString(code UNPARSEcode) bool { func isString(code UNPARSEcode) bool {

View File

@@ -7,7 +7,7 @@ type UNPARSEcode struct {
path string 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) { 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,11 +19,18 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine b
} }
} }
} }
if isSetVariable(code) { if isBrackets(code) {
return parseSetVariable(code, index, codelines)
} else if isBrackets(code) {
return parseBrackets(code, index, codelines) 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) return parseNumber(code)
} else if isNegative(code) { } else if isNegative(code) {
return parseNegative(code, index, codelines) 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 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) { func translate(codelines []UNPARSEcode) ([]any, ArErr) {
translated := []any{} translated := []any{}
for i := 0; i < len(codelines); { for i := 0; i < len(codelines); {

View File

@@ -116,7 +116,7 @@ func setVariableValue(v setVariable, stack stack) (any, ArErr) {
for i := len(stack) - 1; i >= 0; i-- { for i := len(stack) - 1; i >= 0; i-- {
if _, ok := stack[i][v.name]; ok { if _, ok := stack[i][v.name]; ok {
stack[i][v.name] = resp stack[i][v.name] = resp
return stack, ArErr{} return resp, ArErr{}
} }
} }
stack[len(stack)-1][v.name] = resp stack[len(stack)-1][v.name] = resp

View File

@@ -1,3 +1,4 @@
let f(x) = x y = time.now()
log('start')
log(f(1)) time.snooze(1)
log(1e-250-1--1)