diff --git a/src/built-ins.go b/src/built-ins.go index bcf976d..59dd854 100644 --- a/src/built-ins.go +++ b/src/built-ins.go @@ -190,26 +190,6 @@ func makeGlobal() ArObject { for key := range x.obj { newarray = append(newarray, key) } - if callable, ok := x.obj["__dir__"]; ok { - resp, err := runCall( - call{ - callable: callable, - args: []any{}, - }, - stack{newscope()}, - 0, - ) - if err.EXISTS { - return nil, err - } - resp = ArValidToAny(resp) - switch x := resp.(type) { - case []any: - newarray = append(newarray, x...) - default: - return nil, ArErr{TYPE: "TypeError", message: "__dir__ returned type '" + typeof(x) + "'", EXISTS: true} - } - } return ArArray(newarray), ArErr{} } return ArArray([]any{}), ArErr{} diff --git a/src/call.go b/src/call.go index 85a3726..6c4a9ea 100644 --- a/src/call.go +++ b/src/call.go @@ -81,6 +81,7 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) { callable_, err := mapGet(ArMapGet{ x, []any{"__call__"}, + true, c.line, c.code, c.path, diff --git a/src/getIndex.go b/src/getIndex.go index f1d4dc4..75e5e5d 100644 --- a/src/getIndex.go +++ b/src/getIndex.go @@ -14,11 +14,12 @@ var mapGetCompile = makeRegex(`(.|\n)+\.([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|( var indexGetCompile = makeRegex(`(.|\n)+\[(.|\n)+\]( *)`) type ArMapGet struct { - VAL any - args []any - line int - code string - path string + VAL any + args []any + includeConstuctors bool + line int + code string + path string } func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) { @@ -26,16 +27,13 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) { if err.EXISTS { return nil, err } - switch m := resp.(type) { case ArObject: - if obj, ok := m.obj[r.args[0]]; ok { - return obj, ArErr{} + if r.includeConstuctors { + if obj, ok := m.obj[r.args[0]]; ok { + return obj, ArErr{} + } } - } - - switch m := resp.(type) { - case ArObject: if callable, ok := m.obj["__getindex__"]; ok { resp, err := runCall(call{ callable: callable, @@ -47,11 +45,6 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) { if !err.EXISTS { return resp, ArErr{} } - if len(r.args) == 1 && !isUnhashable(r.args[0]) { - if _, ok := m.obj[r.args[0]]; ok { - return m.obj[r.args[0]], ArErr{} - } - } } } @@ -82,7 +75,7 @@ func mapGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapGet if !worked { return ArMapGet{}, false, err, i } - return ArMapGet{resp, []any{key}, code.line, code.realcode, code.path}, true, ArErr{}, 1 + return ArMapGet{resp, []any{key}, true, code.line, code.realcode, code.path}, true, ArErr{}, 1 } func isIndexGet(code UNPARSEcode) bool { @@ -120,7 +113,7 @@ func indexGetParse(code UNPARSEcode, index int, codelines []UNPARSEcode) (ArMapG } continue } - return ArMapGet{tival, args, code.line, code.realcode, code.path}, true, ArErr{}, 1 + return ArMapGet{tival, args, false, code.line, code.realcode, code.path}, true, ArErr{}, 1 } return ArMapGet{}, false, ArErr{ "Syntax Error", diff --git a/src/map.go b/src/map.go index 17a0212..b1cb488 100644 --- a/src/map.go +++ b/src/map.go @@ -9,7 +9,7 @@ import ( var mapCompiled = makeRegex(`( )*{( |\n)*(((.|\n)+)(,(.|\n)+)*)?( |\n)*}( )*`) type createMap struct { - body anymap + body [][2]any code string line int path string @@ -19,11 +19,99 @@ func isMap(code UNPARSEcode) bool { return mapCompiled.MatchString(code.code) } +func runCreateMap(m createMap, stack stack, stacklevel int) (any, ArErr) { + var body = m.body + var newmap = anymap{} + for _, pair := range body { + key := pair[0] + val := pair[1] + keyVal, err := runVal(key, stack, stacklevel+1) + if err.EXISTS { + return nil, err + } + keyVal = ArValidToAny(keyVal) + valVal, err := runVal(val, stack, stacklevel+1) + if err.EXISTS { + return nil, err + } + if isUnhashable(keyVal) { + return nil, ArErr{ + "TypeError", + "unhashable type: '" + typeof(keyVal) + "'", + m.line, + m.path, + m.code, + true, + } + } + newmap[key] = valVal + } + return newmap, ArErr{} +} + func parseMap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) { trimmed := strings.TrimSpace(code.code) trimmed = trimmed[1 : len(trimmed)-1] - debugPrintln(trimmed) - return Map(anymap{}), true, ArErr{}, 1 + if len(trimmed) == 0 { + return createMap{ + body: [][2]any{}, + code: code.realcode, + line: code.line, + path: code.path, + }, true, ArErr{}, 1 + } + var body [][2]any + var LookingAtKey bool = true + var current int + var currentKey any + var countIndex int = 1 + for i := 0; i < len(trimmed); i++ { + var str string + if LookingAtKey { + if trimmed[i] != ':' { + continue + } + str = trimmed[current:i] + } else { + if trimmed[i] != ',' && i != len(trimmed)-1 { + continue + } + if i == len(trimmed)-1 { + str = trimmed[current:] + } else { + str = trimmed[current:i] + } + } + var value any + if LookingAtKey && variableCompile.MatchString(str) { + value = strings.TrimSpace(str) + } else { + val1, worked, err, indexcounted := translateVal(UNPARSEcode{code: str, realcode: code.realcode, line: code.line, path: code.path}, index, codelines, 0) + if !worked || err.EXISTS { + if i == len(trimmed)-1 { + return val1, worked, err, i + } + continue + } + value = val1 + countIndex += indexcounted - 1 + } + if LookingAtKey { + currentKey = value + current = i + 1 + LookingAtKey = false + } else { + body = append(body, [2]any{currentKey, value}) + current = i + 1 + LookingAtKey = true + } + } + return createMap{ + body: body, + code: code.realcode, + line: code.line, + path: code.path, + }, true, ArErr{}, countIndex } func Map(m anymap) ArObject { @@ -211,14 +299,24 @@ func Map(m anymap) ArObject { return true, ArErr{} }, } - obj.obj["__dir__"] = builtinFunc{ - "__dir__", + obj.obj["keys"] = builtinFunc{ + "keys", func(args ...any) (any, ArErr) { - x := []any{} - for k := range m { - x = append(x, k) + if len(args) != 0 { + return nil, ArErr{ + TYPE: "TypeError", + message: "expected 0 arguments, got " + fmt.Sprint(len(args)), + EXISTS: true, + } } - return x, ArErr{} - }} + mutex.RLock() + keys := []any{} + for k := range m { + keys = append(keys, k) + } + mutex.RUnlock() + return keys, ArErr{} + }, + } return obj } diff --git a/src/run.go b/src/run.go index b42f702..976311d 100644 --- a/src/run.go +++ b/src/run.go @@ -181,6 +181,14 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) { break } return runSquareroot(x, stack, stacklevel+1) + case createMap: + if stackoverflow { + linenum = x.line + path = x.path + code = x.code + break + } + return runCreateMap(x, stack, stacklevel+1) case ArImport: if stackoverflow { linenum = x.line