start adding maps

This commit is contained in:
2023-02-26 01:33:02 +00:00
parent 6ef6e051e6
commit f0620354c0
13 changed files with 117 additions and 11 deletions

View File

@@ -1,6 +1,9 @@
package main
import "fmt"
import (
"fmt"
"time"
)
type builtinFunc struct {
name string
@@ -32,3 +35,15 @@ func ArgonMult(args ...any) (any, ArErr) {
return newNumber().Mul(y.(number), x.(number))
}, args), ArErr{}
}
func ArgonSleep(args ...any) (any, ArErr) {
if len(args) > 0 {
float, _ := args[0].(number).Float64()
time.Sleep(time.Duration(float*1000000000) * time.Nanosecond)
}
return nil, ArErr{}
}
func ArgonTimestamp(args ...any) (any, ArErr) {
return newNumber().Quo(newNumber().SetInt64(time.Now().UnixNano()), newNumber().SetInt64(1000000000)), ArErr{}
}

View File

@@ -15,10 +15,22 @@ func init() {
EXISTS: true,
VAL: builtinFunc{"div", ArgonDiv},
}
vars["true"] = variableValue{
EXISTS: true,
VAL: true,
}
vars["false"] = variableValue{
EXISTS: true,
VAL: false,
}
vars["mult"] = variableValue{
EXISTS: true,
VAL: builtinFunc{"mult", ArgonMult},
}
vars["time"] = variableValue{
EXISTS: true,
VAL: ArMap{"snooze": builtinFunc{"snooze", ArgonSleep}, "now": builtinFunc{"now", ArgonTimestamp}},
}
pi, _ := newNumber().SetString("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989")
vars["PI"] = variableValue{
EXISTS: true,

View File

@@ -11,6 +11,7 @@ type call struct {
args []any
code string
line int
path string
}
func isCall(code UNPARSEcode) bool {
@@ -50,10 +51,10 @@ func parseCall(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
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
return call{callable: callable, args: arguments, line: code.line, code: code.realcode, path: code.path}, true, ArErr{}, 1
}
func runCall(c call, stack []map[string]variableValue) (any, ArErr) {
func runCall(c call, stack stack) (any, ArErr) {
callable, err := runVal(c.callable, stack)
if err.EXISTS {
return nil, err
@@ -70,7 +71,7 @@ func runCall(c call, stack []map[string]variableValue) (any, ArErr) {
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", "cannot call a class", c.line, c.path, c.code, true}
}
return nil, ArErr{"Runtime Error", typeof(callable) + "' is not callable", c.line, "", c.code, true}
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
}

View File

@@ -4,6 +4,6 @@ type Callable struct {
name string
params []string
code []any
stack []map[string]variableValue
stack stack
line int
}

View File

@@ -98,7 +98,7 @@ func importMod(realpath string, origin string, main bool) ArErr {
if translationerr.EXISTS {
return translationerr
}
_, runimeErr := run(translated, []map[string]variableValue{vars})
_, runimeErr := run(translated, stack{vars})
if runimeErr.EXISTS {
return runimeErr
}

View File

@@ -7,6 +7,8 @@ import (
// args without the program path
var Args = os.Args[1:]
type stack = []map[string]variableValue
func main() {
ex, e := os.Getwd()
if e != nil {

68
src/map.go Normal file
View File

@@ -0,0 +1,68 @@
package main
import (
"fmt"
"strings"
)
type ArMap = map[any]any
var mapGetCompile = makeRegex(".+\\.([a-zA-Z_])([a-zA-Z0-9_])*( *)")
type ArMapGet struct {
VAL any
key any
line int
code string
path string
}
func mapGet(r ArMapGet, stack stack) (any, ArErr) {
resp, err := runVal(r.VAL, stack)
if err.EXISTS {
return nil, err
}
key, err := runVal(r.key, stack)
if err.EXISTS {
return nil, err
}
switch m := resp.(type) {
case ArMap:
if _, ok := m[key]; !ok {
return nil, ArErr{
"KeyError",
"key '" + fmt.Sprint(key) + "' not found",
r.line,
r.path,
r.code,
true,
}
}
return m[key], ArErr{}
}
return nil, ArErr{
"TypeError",
"cannot read " + anyToArgon(key, true) + " from type '" + typeof(resp) + "'",
r.line,
r.path,
r.code,
true,
}
}
func isMapGet(code UNPARSEcode) bool {
return mapGetCompile.MatchString(code.code)
}
func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet, bool, ArErr, int) {
trim := strings.TrimSpace(code.code)
split := strings.Split(trim, ".")
start := strings.Join(split[:len(split)-1], ".")
key := split[len(split)-1]
resp, worked, err, i := translateVal(UNPARSEcode{code: start, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, false)
if !worked {
return ArMapGet{}, false, err, i
}
k := translateString{key, code.realcode, code.line}
return ArMapGet{resp, k, code.line, code.realcode, code.path}, true, ArErr{}, 1
}

View File

@@ -1,7 +1,7 @@
package main
// returns (number|string|nil), error
func runVal(line any, stack []map[string]variableValue) (any, ArErr) {
func runVal(line any, stack stack) (any, ArErr) {
switch x := line.(type) {
case translateNumber:
return (x.number), ArErr{}
@@ -11,12 +11,14 @@ func runVal(line any, stack []map[string]variableValue) (any, ArErr) {
return runCall(x, stack)
case accessVariable:
return readVariable(x, stack)
case ArMapGet:
return mapGet(x, stack)
}
panic("unreachable")
}
// returns error
func run(translated []any, stack []map[string]variableValue) (any, ArErr) {
func run(translated []any, stack stack) (any, ArErr) {
for _, val := range translated {
_, err := runVal(val, stack)
if err.EXISTS {

View File

@@ -23,6 +23,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine b
return parseCall(code, index, codelines)
} else if isVariable(code) {
return parseVariable(code)
} else if isMapGet(code) {
return mapGetParse(code, index, codelines)
} else if isNumber(code) {
return parseNumber(code)
} else if isString(code) {

View File

@@ -46,7 +46,7 @@ func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
return accessVariable{name: name, code: code.code, line: code.line}, true, ArErr{}, 1
}
func readVariable(v accessVariable, stack []map[string]variableValue) (any, ArErr) {
func readVariable(v accessVariable, stack stack) (any, ArErr) {
for i := len(stack) - 1; i >= 0; i-- {
if val, ok := stack[i][v.name]; ok {
return val.VAL, ArErr{}