Implemented dot notation (getter)
h3rald h3rald@h3rald.com
Sun, 05 May 2024 11:33:40 +0200
4 files changed,
46 insertions(+),
15 deletions(-)
M
minpkg/core/interpreter.nim
→
minpkg/core/interpreter.nim
@@ -27,7 +27,7 @@ var COMPILEDMINFILES* {.threadvar.}: CritBitTree[MinOperatorProc]
var COMPILEDASSETS* {.threadvar.}: CritBitTree[string] var CACHEDMODULES* {.threadvar.}: CritBitTree[MinValue] -const USER_SYMBOL_REGEX* = "^[a-zA-Z_][a-zA-Z0-9/!?+*._-]*$" +const USER_SYMBOL_REGEX* = "^[a-zA-Z_][a-zA-Z0-9/!?+*_-]*$" proc diff*(a, b: seq[MinValue]): seq[MinValue] = result = newSeq[MinValue](0)@@ -250,6 +250,24 @@ column: i.currSym.column,
outerSym: i.currSym.symVal, docComment: i.currSym.docComment) +proc getSymbolPath*(i: In, symbol: string) = + let parts = symbol.split(".") + if parts.len < 2: + raiseInvalid("Dictionary identifier not specified") + i.pushSym parts[0] + for p in 0..parts.len-2: + let mdl = i.pop + if mdl.kind != minDictionary: + raiseInvalid("$1 is not a dictionary" % [mdl.getString]) + let symId = parts[p+1] + let origScope = i.scope + i.scope = mdl.scope + if not i.scope.parent.isNil: + i.scope.parent = origScope + let sym = i.scope.getSymbol(symId) + i.apply(sym) + i.scope = origScope + proc push*(i: In, val: MinValue) = if val.kind == minSymbol: i.debug(val)@@ -265,8 +283,11 @@ raise MinReturnException(msg: "return symbol found")
if i.scope.hasSymbol(symbol): i.apply i.scope.getSymbol(symbol), symbol else: + # Process dictionary access + if symbol.contains('.'): + i.getSymbolPath(symbol) # Check if symbol ends with ! (auto-popping) - if symbol.len > 1 and symbol[symbol.len-1] == '!': + elif symbol.len > 1 and symbol[symbol.len-1] == '!': let apSymbol = symbol[0..symbol.len-2] if i.scope.hasSymbol(apSymbol): i.apply i.scope.getSymbol(apSymbol)
M
minpkg/core/shell.nim
→
minpkg/core/shell.nim
@@ -54,11 +54,11 @@ if word.startsWith("#"):
return symbols.mapIt("#" & $it) if word.startsWith(">"): return symbols.mapIt(">" & $it) - if word.startsWith("*") and word.contains("/"): - let dicts = word.substr(1).split("/") + if word.contains("."): + let dicts = word.split(".") var op: MinOperator var dict: MinValue - var path = "*" + var path = "" for d in dicts: if dict.isNil: if i.scope.symbols.hasKey(d):@@ -67,23 +67,15 @@ if op.kind == minProcOp and not op.mdl.isNil:
dict = op.mdl elif op.kind == minValOp and op.val.kind == minDictionary: dict = op.val - path &= d & "/" + path &= d & "." elif dict.dVal.hasKey(d): op = dict.dVal[d] if op.kind == minProcOp and not op.mdl.isNil: dict = op.mdl elif op.kind == minValOp and op.val.kind == minDictionary: dict = op.val - path &= d & "/" + path &= d & "." return dict.dVal.keys.toSeq.mapIt(path & it) - if word.startsWith("*"): - let filterProc = proc (it: string): bool = - let op = i.scope.symbols[it] - if op.kind == minProcOp and not op.mdl.isNil: - return true - else: - return op.kind == minValOp and op.val.kind == minDictionary - return symbols.filter(filterProc).mapIt("*" & $it) if word.startsWith("("): return symbols.mapIt("(" & $it) if word.startsWith("<"):@@ -114,6 +106,14 @@ dir = getCurrentDir()
return toSeq(walkDir(dir, true)).filterIt( it.path.toLowerAscii.startsWith(f.toLowerAscii)).mapIt("\"$1\"" % [ it.path.replace("\\", "/")]) + if word.startsWith("*"): + let filterProc = proc (it: string): bool = + let op = i.scope.symbols[it] + if op.kind == minProcOp and not op.mdl.isNil: + return true + else: + return op.kind == minValOp and op.val.kind == minDictionary + return symbols.filter(filterProc).mapIt("*" & $it) return symbols proc p(s: string, color = fgWhite) =
M
next-release.md
→
next-release.md
@@ -1,3 +1,8 @@
+### BREAKING CHANGES + +- User-defined symbols can no longer contain dots (`.`). + + ### New Features - Added a new `color` symbol to the `io` module to enable/disable terminal color output.
M
tests/global.min
→
tests/global.min
@@ -351,6 +351,11 @@ 11 test
and ) *test/assert + ( + {{1 :aa} :a 2 :b} :test1 + test1.b test1.a.aa + 3 == + ) *test/assert + *test/report ; Tidy up clear-stack