all repos — min @ 7241a8ca4776328e639c5912e82acd9be2f775a4

A small but practical concatenative programming language.

Rewrote dictionary operations.
h3rald h3rald@h3rald.com
Sat, 26 May 2018 17:49:51 +0200
commit

7241a8ca4776328e639c5912e82acd9be2f775a4

parent

ece28e8edb437c639e050bbc9a1297c7625516e8

4 files changed, 42 insertions(+), 64 deletions(-)

jump to
M core/parser.nimcore/parser.nim

@@ -97,6 +97,7 @@ case kind*: MinOperatorKind

of minProcOp: prc*: MinOperatorProc of minValOp: + quotation*: bool val*: MinValue MinStack* = seq[MinValue] In* = var MinInterpreter

@@ -597,7 +598,10 @@ return q

of minDictionary: var d = "{" for i in a.dVal.pairs: - d = d & $i.val.val & " :" & $i.key & " " + var v = $i.val.val + if (not i.val.quotation): + v = v[1 .. v.len-2] + d = d & v & " :" & $i.key & " " if not a.objType.isNil: d = d & ";" & a.objType d = d.strip & "}"

@@ -626,7 +630,10 @@ return q

of minDictionary: var d = "{" for i in a.dVal.pairs: - d = d & $i.val.val & " :" & $i.key & " " + var v = $i.val.val + if (not i.val.quotation): + v = v[1 .. v.len-2] + d = d & v & " :" & $i.key & " " if not a.objType.isNil: d = d & ";" & a.objType d = d.strip & "}"

@@ -662,14 +669,7 @@ proc isStringLike*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}=

return s.isSymbol or s.isString or (s.isQuotation and s.qVal.len == 1 and s.qVal[0].isSymbol) proc isDictionary*(q: MinValue): bool {.extern:"min_exported_symbol_$1".}= - if not q.isQuotation: - return false - if q.qVal.len == 0: - return true - for val in q.qVal: - if not val.isQuotation or val.qVal.len != 2 or not val.qVal[0].isString: - return false - return true + return q.kind == minDictionary proc isTypedDictionary*(q: MinValue): bool {.extern:"min_exported_symbol_$1".}= if q.isDictionary:
M core/utils.nimcore/utils.nim

@@ -50,63 +50,42 @@

proc dget*(q: MinValue, s: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= if not q.isDictionary: raiseInvalid("Value is not a dictionary") - for v in q.qVal: - if v.qVal[0].getString == s.getString: - return v.qVal[1] - raiseInvalid("Dictionary key '$1' not found" % s.getString) + let val = q.dVal[s.getString] + return val.val.qVal[0] proc dhas*(q: MinValue, s: MinValue): bool {.extern:"min_exported_symbol_$1".}= if not q.isDictionary: raiseInvalid("Value is not a dictionary") - for v in q.qVal: - if v.qVal[0].getString == s.getString: - return true - return false + return q.dVal.contains(s.getString) -proc ddel*(i: In, p: MinValue, s: MinValue): MinValue {.discardable, extern:"min_exported_symbol_$1".} = +proc ddel*(i: In, p: var MinValue, s: MinValue): MinValue {.discardable, extern:"min_exported_symbol_$1".} = if not p.isDictionary: raiseInvalid("Value is not a dictionary") - var q = newVal(p.qVal, i.scope) - var found = false - var c = -1 - for v in q.qVal: - c.inc - if v.qVal[0].getString == s.getString: - found = true - break - if found: - q.qVal.delete(c) - return q + excl(p.scope.symbols, s.getString) + return p proc dset*(i: In, p: MinValue, s: MinValue, m: MinValue): MinValue {.discardable, extern:"min_exported_symbol_$1".}= if not p.isDictionary: raiseInvalid("Value is not a dictionary") - var q = newVal(p.qVal, i.scope) - var found = false - var c = -1 - for v in q.qVal: - c.inc - if v.qVal[0].getString == s.getString: - found = true - break - if found: - q.qVal.delete(c) - q.qVal.insert(@[s.getString.newVal, m].newVal(i.scope), c) - else: - q.qVal.add(@[s.getString.newVal, m].newVal(i.scope)) - return q + var q = m + if not q.isQuotation: + q = @[q].newVal(i.scope) + p.scope.symbols[s.getString] = MinOperator(kind: minValOp, val: q, sealed: false) + return p proc keys*(i: In, q: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= # Assumes q is a dictionary - result = newSeq[MinValue](0).newVal(i.scope) - for v in q.qVal: - result.qVal.add v.qVal[0].getString.newVal + var r = newSeq[MinValue](0) + for i in q.dVal.keys: + r.add newVal(i) + return r.newVal(i.scope) proc values*(i: In, q: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= # Assumes q is a dictionary - result = newSeq[MinValue](0).newVal(i.scope) - for v in q.qVal: - result.qVal.add v.qVal[1] + var r = newSeq[MinValue](0) + for i in q.dVal.values: + r.add i.val + return r.newVal(i.scope) # JSON interop

@@ -126,15 +105,9 @@ return %a.intVal

of minFloat: return %a.floatVal of minQuotation: - # TODO Review - if a.isDictionary: - result = newJObject() - for i in a.qVal: - result[$i.qVal[0].getString] = %i.qVal[1] - else: - result = newJArray() - for i in a.qVal: - result.add %i + result = newJArray() + for i in a.qVal: + result.add %i of minDictionary: result = newJObject() for i in a.dVal.pairs:

@@ -159,6 +132,7 @@ result = json.getStr.newVal

of JObject: var res = newSeq[MinValue](0) for key, value in json.pairs: + #TODO res.add @[key.newVal, i.fromJson(value)].newVal(i.scope) return res.newVal(i.scope) of JArray:
M lib/min_lang.nimlib/min_lang.nim

@@ -96,26 +96,30 @@ let vals = i.expect("'sym", "a")

let sym = vals[0] var q1 = vals[1] # existing (auto-quoted) var symbol: string + var isQuot = true if not q1.isQuotation: q1 = @[q1].newVal(i.scope) + isQuot = false symbol = sym.getString if not symbol.match "^[a-zA-Z_][a-zA-Z0-9/!?+*._-]*$": 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) + i.scope.symbols[symbol] = MinOperator(kind: minValOp, val: q1, sealed: false, quotation: isQuot) def.symbol("bind") do (i: In): let vals = i.expect("'sym", "a") let sym = vals[0] var q1 = vals[1] # existing (auto-quoted) var symbol: string + var isQuot = true if not q1.isQuotation: q1 = @[q1].newVal(i.scope) + isQuot = false symbol = sym.getString info "[bind] $1 = $2" % [symbol, $q1] - let res = i.scope.setSymbol(symbol, MinOperator(kind: minValOp, val: q1)) + let res = i.scope.setSymbol(symbol, MinOperator(kind: minValOp, val: q1, quotation: isQuot)) if not res: raiseUndefined("Attempting to bind undefined symbol: " & symbol)

@@ -133,7 +137,7 @@ var code = vals[1]

code.filename = i.filename i.dequote(code) info("[module] $1 ($2 symbols)" % [name.getString, $code.scope.symbols.len]) - i.scope.symbols[name.getString] = MinOperator(kind: minValOp, val: @[code].newVal(i.scope)) + i.scope.symbols[name.getString] = MinOperator(kind: minValOp, val: @[code].newVal(i.scope), quotation: true) def.symbol("import") do (i: In): var vals = i.expect("'sym")

@@ -493,7 +497,7 @@ let json = MINSYMBOLS.readFile.parseJson

if not json.hasKey(sym): raiseUndefined("Symbol '$1' not found." % sym) let val = i.fromJson(json[sym]) - i.scope.symbols[sym] = MinOperator(kind: minValOp, val: val) + i.scope.symbols[sym] = MinOperator(kind: minValOp, val: val, quotation: true) def.symbol("stored-symbols") do (i: In): var q = newSeq[MinValue](0)
M lib/min_seq.nimlib/min_seq.nim

@@ -364,7 +364,7 @@

def.symbol("ddel") do (i: In): let vals = i.expect("'sym", "dict") let k = vals[0] - let d = vals[1] + var d = vals[1] i.push i.ddel(d, k) def.symbol("dkeys") do (i: In):