all repos — min @ 14b5c6c0b2e723bd4cf18f877342ab9589c67511

A small but practical concatenative programming language.

Implementing :mdl.sym (not working)
h3rald h3rald@h3rald.com
Sat, 11 May 2024 17:40:44 +0200
commit

14b5c6c0b2e723bd4cf18f877342ab9589c67511

parent

6ab57998aaf63e146352babcb3e1272ddf19254c

2 files changed, 64 insertions(+), 2 deletions(-)

jump to
M minpkg/core/interpreter.nimminpkg/core/interpreter.nim

@@ -3,6 +3,7 @@ std/[streams,

strutils, sequtils, os, + nre, osproc, critbits, json,

@@ -267,6 +268,62 @@ i.scope.parent = origScope

let sym = i.scope.getSymbol(symId) i.apply(sym) i.scope = origScope + +proc setSymbolPath*(i: In, symbol: string, q1: MinValue, mustExist: bool) = + let parts = symbol.split(".") + if parts.len < 2: + raiseInvalid("Dictionary identifier not specified") + i.pushSym parts[0] + var count = 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 + var sym: MinOperator + var notFound = false + try: + sym = i.scope.getSymbol(symId) + except CatchableError: + notFound = true + discard + if (notFound and mustExist): + raiseInvalid("Symbol $# does not exist" % [symId]) + if count >= parts.len-2: + if not symId.contains re(USER_SYMBOL_REGEX): + raiseInvalid("Symbol identifier '$1' contains invalid characters." % symId) + info "[define] $1 = $2" % [symbol, $q1] + if mdl.scope.symbols.hasKey(symId) and mdl.scope.symbols[symId].sealed: + raiseUndefined("Attempting to redefine sealed symbol '$1'" % [symbol]) + mdl.scope.symbols[symId] = MinOperator(kind: minValOp, val: q1, + sealed: false, quotation: q1.isQuotation) + i.scope = origScope + count = count+1 + +proc getSymbolObjectPath*(i: In, symbol: string): MinOperator = + let parts = symbol.split(".") + if parts.len < 2: + raiseInvalid("Dictionary identifier not specified") + i.pushSym parts[0] + var count = 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 + result = i.scope.getSymbol(symId) + if count < parts.len-2: + i.apply(result) + i.scope = origScope + count = count+1 proc push*(i: In, val: MinValue) = if val.kind == minSymbol:
M minpkg/lib/min_global.nimminpkg/lib/min_global.nim

@@ -506,16 +506,18 @@ let vals = i.expect("'sym", "a")

let sym = vals[0] var q1 = vals[1] # existing (auto-quoted) var symbol: string - var isQuot = q1.isQuotation q1 = @[q1].newVal symbol = sym.getString + if symbol.contains ".": + i.setSymbolPath(symbol, q1, false) + return if not symbol.contains re(USER_SYMBOL_REGEX): raiseInvalid("Symbol identifier '$1' contains invalid characters." % symbol) info "[define] $1 = $2" % [symbol, $q1] if i.scope.symbols.hasKey(symbol) and i.scope.symbols[symbol].sealed: raiseUndefined("Attempting to redefine sealed symbol '$1'" % [symbol]) i.scope.symbols[symbol] = MinOperator(kind: minValOp, val: q1, - sealed: false, quotation: isQuot) + sealed: false, quotation: q1.isQuotation) def.symbol("typealias") do (i: In): let vals = i.expect("'sym", "'sym")

@@ -554,6 +556,9 @@ var symbol: string

var isQuot = q1.isQuotation q1 = @[q1].newVal symbol = sym.getString + if symbol.contains ".": + i.setSymbolPath(symbol, q1, true) + return info "[bind] $1 = $2" % [symbol, $q1] let res = i.scope.setSymbol(symbol, MinOperator(kind: minValOp, val: q1, quotation: isQuot))