Skip to content

Commit d0d644f

Browse files
committed
Merge branch 'next'
2 parents 1f74aba + 61dfd2e commit d0d644f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1915
-1124
lines changed

help.json

+567-173
Large diffs are not rendered by default.

min.nim

+2-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import
1111
env,
1212
parser,
1313
value,
14-
scope,
1514
interpreter,
1615
stdlib,
1716
shell,
@@ -29,7 +28,6 @@ export
2928
utils,
3029
value,
3130
shell,
32-
scope,
3331
stdlib,
3432
min_global,
3533
niftylogger
@@ -209,9 +207,8 @@ when isMainModule:
209207
of "dev", "d":
210208
DEV = true
211209
of "log", "l":
212-
if file == "":
213-
var val = val
214-
niftylogger.setLogLevel(val)
210+
var v = val
211+
niftylogger.setLogLevel(v)
215212
of "passN", "n":
216213
NIMOPTIONS = val
217214
of "help", "h":

min.nimble

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# Package
22

3-
version = "0.43.1"author = "Fabio Cevasco"
3+
version = "0.44.0"
4+
author = "Fabio Cevasco"
45
description = "A small but practical concatenative programming language and shell."
56
license = "MIT"
67
bin = @["min"]
78
installExt = @["nim", "c", "h", "a"]
89
installFiles = @["min.yml", "min.nim", "prelude.min", "help.json"]
10+
skipFiles = @["mintool.min"]
911
installDirs = @["minpkg"]
1012

1113
# Dependencies
@@ -14,4 +16,4 @@ requires "nim >= 2.0.0 & < 3.0.0"
1416
requires "checksums"
1517
requires "zippy >= 0.5.6 & < 0.6.0"
1618
requires "nimquery >= 2.0.1 & < 3.0.0"
17-
requires "minline >= 0.1.1 & < 0.2.0"
19+
requires "minline >= 0.1.2 & < 0.2.0"

min.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
author: Fabio Cevasco
22
description: A small but practical concatenative programming language and shell.
3-
id: 153992690
3+
id: 154260810
44
name: min
5-
version: 0.43.1
5+
version: 0.44.0

minpkg/core/env.nim

+2
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ var MINCOMPILED* {.threadvar.}: bool
2222
MINCOMPILED = false
2323
var DEV* {.threadvar.}: bool
2424
DEV = false
25+
var COLOR* {.threadvar.}: bool
26+
COLOR = true
2527

minpkg/core/interpreter.nim

+40-8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import
33
strutils,
44
sequtils,
55
os,
6+
nre,
67
osproc,
78
critbits,
89
json,
@@ -12,7 +13,6 @@ import
1213
import
1314
baseutils,
1415
value,
15-
scope,
1616
parser
1717

1818
type
@@ -27,7 +27,8 @@ var COMPILEDMINFILES* {.threadvar.}: CritBitTree[MinOperatorProc]
2727
var COMPILEDASSETS* {.threadvar.}: CritBitTree[string]
2828
var CACHEDMODULES* {.threadvar.}: CritBitTree[MinValue]
2929

30-
const USER_SYMBOL_REGEX* = "^[a-zA-Z_][a-zA-Z0-9/!?+*._-]*$"
30+
const USER_SYMBOL_REGEX* = "^[a-zA-Z_][a-zA-Z0-9/!?+*_-]*$"
31+
const USER_PATH_SYMBOL_REGEX* = "^[a-zA-Z_][a-zA-Z0-9/.!?+*_-]*$"
3132

3233
proc diff*(a, b: seq[MinValue]): seq[MinValue] =
3334
result = newSeq[MinValue](0)
@@ -193,7 +194,20 @@ proc copyDict*(i: In, val: MinValue): MinValue =
193194

194195
proc apply*(i: In, op: MinOperator, sym = "") {.effectsOf: op.} =
195196
if op.kind == minProcOp:
196-
op.prc(i)
197+
if not op.mdl.isNil and not op.mdl.scope.isNil and not i.scope.hasParent op.mdl.scope:
198+
# Capture closures at module level
199+
let origScope = i.scope
200+
let origParentScope = i.scope.parent
201+
let origMdlParentScope = op.mdl.scope.parent
202+
i.scope = op.mdl.scope
203+
i.scope.parent = origScope
204+
i.scope.parent.parent = origParentScope
205+
op.prc(i)
206+
i.scope = origScope
207+
i.scope.parent = origParentScope
208+
op.mdl.scope.parent = origMdlParentScope
209+
else:
210+
op.prc(i)
197211
else:
198212
if op.val.kind == minQuotation:
199213
var newscope = newScopeRef(i.scope)
@@ -237,6 +251,7 @@ proc pop*(i: In): MinValue =
237251
if i.stack.len > 0:
238252
return i.stack.pop
239253
else:
254+
debug "pop - empty stack!"
240255
raiseEmptyStack()
241256

242257
# Inherit file/line/column from current symbol
@@ -262,27 +277,38 @@ proc push*(i: In, val: MinValue) =
262277
let symbol = val.symVal
263278
if symbol == "return":
264279
raise MinReturnException(msg: "return symbol found")
265-
if i.scope.hasSymbol(symbol):
266-
i.apply i.scope.getSymbol(symbol), symbol
280+
i.debug("push: $#" % [symbol])
281+
let op = i.scope.getSymbol(symbol)
282+
if not op.isNull:
283+
i.debug("push: symbol found: $#" % [symbol])
284+
i.apply op, symbol
267285
else:
268286
# Check if symbol ends with ! (auto-popping)
269287
if symbol.len > 1 and symbol[symbol.len-1] == '!':
288+
i.debug("push - checking auto-popping symbol: $#" % [symbol])
270289
let apSymbol = symbol[0..symbol.len-2]
271-
if i.scope.hasSymbol(apSymbol):
272-
i.apply i.scope.getSymbol(apSymbol)
290+
let apOp = i.scope.getSymbol(apSymbol)
291+
if not apOp.isNull:
292+
i.apply apOp
273293
discard i.pop
274294
else:
295+
i.debug("push - checking sigil: $#" % [symbol])
296+
# Check user-defined sigil
275297
var qIndex = symbol.find('"')
276298
if qIndex > 0:
277299
let sigil = symbol[0..qIndex-1]
300+
i.debug("push - checking user sigil: $#" % [sigil])
278301
if not i.scope.hasSigil(sigil):
279302
raiseUndefined("Undefined sigil '$1'"%sigil)
280303
i.stack.add(MinValue(kind: minString, strVal: symbol[
281304
qIndex+1..symbol.len-2]))
282305
i.apply(i.scope.getSigil(sigil))
283306
else:
307+
# Check system sigil
284308
let sigil = "" & symbol[0]
309+
i.debug("push - checking system sigil: $#" % [sigil])
285310
if symbol.len > 1 and i.scope.hasSigil(sigil):
311+
i.debug("Processing sigil: $# ($#)" % [sigil, symbol])
286312
i.stack.add(MinValue(kind: minString, strVal: symbol[
287313
1..symbol.len-1]))
288314
i.apply(i.scope.getSigil(sigil))
@@ -304,6 +330,7 @@ proc peek*(i: MinInterpreter): MinValue =
304330
if i.stack.len > 0:
305331
return i.stack[i.stack.len-1]
306332
else:
333+
debug "peek - empty stack!"
307334
raiseEmptyStack()
308335

309336
template handleErrors*(i: In, body: untyped) =
@@ -369,6 +396,8 @@ proc initCompiledFile*(i: In, files: seq[string]): seq[string] {.discardable.} =
369396
result.add "import critbits"
370397
if ASSETPATH != "":
371398
result.add "import base64"
399+
result.add "import logging"
400+
result.add "logging.setLogFilter(logging.lvlNotice)"
372401
result.add "MINCOMPILED = true"
373402
result.add "var i = newMinInterpreter(\"$#\")" % i.filename
374403
result.add "i.stdLib()"
@@ -436,7 +465,10 @@ proc require*(i: In, s: string, parseOnly = false): MinValue {.discardable.} =
436465
result = newDict(i2.scope)
437466
result.objType = "module"
438467
for key, value in i2.scope.symbols.pairs:
439-
result.scope.symbols[key] = value
468+
var v = value
469+
if v.kind == minProcOp:
470+
v.mdl = result
471+
result.scope.symbols[key] = v
440472
CACHEDMODULES[s] = result
441473

442474
proc parse*(i: In, s: string, name = "<parse>"): MinValue =

minpkg/core/niftylogger.nim

+8-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import
44
terminal,
55
exitprocs]
66

7+
import
8+
./env
9+
710
if isatty(stdin):
811
addExitProc(resetAttributes)
912

@@ -34,10 +37,12 @@ method log*(logger: NiftyLogger; level: Level; args: varargs[string, `$`]) =
3437
f = stderr
3538
let ln = substituteLog(logger.fmtStr, level, args)
3639
let prefix = level.logPrefix()
37-
f.setForegroundColor(prefix.color)
40+
if COLOR:
41+
f.setForegroundColor(prefix.color)
3842
f.write(prefix.msg)
3943
f.write(ln)
40-
resetAttributes()
44+
if COLOR:
45+
resetAttributes()
4146
f.write("\n")
4247
if level in {lvlError, lvlFatal}: flushFile(f)
4348

@@ -69,5 +74,5 @@ proc setLogLevel*(val: var string): string {.discardable.} =
6974
else:
7075
val = "warn"
7176
lvl = lvlWarn
72-
setLogFilter(lvl)
77+
logging.setLogFilter(lvl)
7378
return val

0 commit comments

Comments
 (0)