all repos — min @ a2c33d1ee4bfa82cd425a65548caac5efc24e03f

A small but practical concatenative programming language.

Removed support for dynamic library creation.
h3rald h3rald@h3rald.com
Sun, 27 Dec 2020 13:34:13 +0000
commit

a2c33d1ee4bfa82cd425a65548caac5efc24e03f

parent

5781b90db6ac2593a4259427f95a7210d5be3625

M core/fileutils.nimcore/fileutils.nim

@@ -1,100 +1,100 @@

-import - os - -# Filetype and permissions - -proc filetype*(p: PathComponent): string {.extern:"min_exported_symbol_$1".}= - case p - of pcFile: - return "file" - of pcLinkToFile: - return "filelink" - of pcDir: - return "dir" - of pcLinkToDir: - return "dirlink" - -proc unixPermissions*(s: set[FilePermission]): int {.extern:"min_exported_symbol_$1".}= - result = 0 - for p in s: - case p: - of fpUserRead: - result += 400 - of fpUserWrite: - result += 200 - of fpUserExec: - result += 100 - of fpGroupRead: - result += 40 - of fpGroupWrite: - result += 20 - of fpGroupExec: - result += 10 - of fpOthersRead: - result += 4 - of fpOthersWrite: - result += 2 - of fpOthersExec: - result += 1 - -proc toFilePermissions*(p: BiggestInt): set[FilePermission] {.extern:"min_exported_symbol_$1".}= - let user = ($p)[0].int - let group = ($p)[1].int - let others = ($p)[2].int - if user == 1: - result.incl fpUserExec - if user == 2: - result.incl fpUserWrite - if user == 3: - result.incl fpUserExec - result.incl fpUserWrite - if user == 4: - result.incl fpUserRead - if user == 5: - result.incl fpUserRead - result.incl fpUserExec - if user == 6: - result.incl fpUserRead - result.incl fpUserWrite - if user == 7: - result.incl fpUserRead - result.incl fpUserWrite - result.incl fpUserExec - if group == 1: - result.incl fpGroupExec - if group == 2: - result.incl fpGroupWrite - if group == 3: - result.incl fpGroupExec - result.incl fpGroupWrite - if group == 4: - result.incl fpGroupRead - if group == 5: - result.incl fpGroupRead - result.incl fpGroupExec - if group == 6: - result.incl fpGroupRead - result.incl fpGroupWrite - if group == 7: - result.incl fpGroupRead - result.incl fpGroupWrite - result.incl fpGroupExec - if others == 1: - result.incl fpOthersExec - if others == 2: - result.incl fpOthersWrite - if others == 3: - result.incl fpOthersExec - result.incl fpOthersWrite - if others == 4: - result.incl fpOthersRead - if others == 5: - result.incl fpOthersRead - result.incl fpOthersExec - if others == 6: - result.incl fpOthersRead - result.incl fpOthersWrite - if others == 7: - result.incl fpOthersRead - result.incl fpOthersWrite - result.incl fpOthersExec +import + os + +# Filetype and permissions + +proc filetype*(p: PathComponent): string = + case p + of pcFile: + return "file" + of pcLinkToFile: + return "filelink" + of pcDir: + return "dir" + of pcLinkToDir: + return "dirlink" + +proc unixPermissions*(s: set[FilePermission]): int = + result = 0 + for p in s: + case p: + of fpUserRead: + result += 400 + of fpUserWrite: + result += 200 + of fpUserExec: + result += 100 + of fpGroupRead: + result += 40 + of fpGroupWrite: + result += 20 + of fpGroupExec: + result += 10 + of fpOthersRead: + result += 4 + of fpOthersWrite: + result += 2 + of fpOthersExec: + result += 1 + +proc toFilePermissions*(p: BiggestInt): set[FilePermission] = + let user = ($p)[0].int + let group = ($p)[1].int + let others = ($p)[2].int + if user == 1: + result.incl fpUserExec + if user == 2: + result.incl fpUserWrite + if user == 3: + result.incl fpUserExec + result.incl fpUserWrite + if user == 4: + result.incl fpUserRead + if user == 5: + result.incl fpUserRead + result.incl fpUserExec + if user == 6: + result.incl fpUserRead + result.incl fpUserWrite + if user == 7: + result.incl fpUserRead + result.incl fpUserWrite + result.incl fpUserExec + if group == 1: + result.incl fpGroupExec + if group == 2: + result.incl fpGroupWrite + if group == 3: + result.incl fpGroupExec + result.incl fpGroupWrite + if group == 4: + result.incl fpGroupRead + if group == 5: + result.incl fpGroupRead + result.incl fpGroupExec + if group == 6: + result.incl fpGroupRead + result.incl fpGroupWrite + if group == 7: + result.incl fpGroupRead + result.incl fpGroupWrite + result.incl fpGroupExec + if others == 1: + result.incl fpOthersExec + if others == 2: + result.incl fpOthersWrite + if others == 3: + result.incl fpOthersExec + result.incl fpOthersWrite + if others == 4: + result.incl fpOthersRead + if others == 5: + result.incl fpOthersRead + result.incl fpOthersExec + if others == 6: + result.incl fpOthersRead + result.incl fpOthersWrite + if others == 7: + result.incl fpOthersRead + result.incl fpOthersWrite + result.incl fpOthersExec
M core/interpreter.nimcore/interpreter.nim

@@ -30,20 +30,20 @@ var COMPILEDASSETS* {.threadvar.}: CritBitTree[string]

const USER_SYMBOL_REGEX* = "^[a-zA-Z_][a-zA-Z0-9/!?+*._-]*$" -proc raiseRuntime*(msg: string, data: MinValue) {.extern:"min_exported_symbol_$1".}= +proc raiseRuntime*(msg: string, data: MinValue) = data.objType = "error" raise MinRuntimeError(msg: msg, data: data) -proc dump*(i: MinInterpreter): string {.extern:"min_exported_symbol_$1".}= +proc dump*(i: MinInterpreter): string = var s = "" for item in i.stack: s = s & $item & " " return s -proc debug*(i: In, value: MinValue) {.extern:"min_exported_symbol_$1".}= +proc debug*(i: In, value: MinValue) = debug("(" & i.dump & $value & ")") -proc debug*(i: In, value: string) {.extern:"min_exported_symbol_$1_2".}= +proc debug*(i: In, value: string) = debug(value) template withScope*(i: In, res:ref MinScope, body: untyped): untyped =

@@ -71,7 +71,7 @@ body

finally: i.scope = origScope -proc newMinInterpreter*(filename = "input", pwd = ""): MinInterpreter {.extern:"min_exported_symbol_$1".}= +proc newMinInterpreter*(filename = "input", pwd = ""): MinInterpreter = var path = pwd when not defined(mini): if not pwd.isAbsolute:

@@ -93,7 +93,7 @@ currSym: MinValue(column: 1, line: 1, kind: minSymbol, symVal: "")

) return i -proc copy*(i: MinInterpreter, filename: string): MinInterpreter {.extern:"min_exported_symbol_$1_2".}= +proc copy*(i: MinInterpreter, filename: string): MinInterpreter = var path = filename when not defined(mini): if not filename.isAbsolute:

@@ -107,13 +107,13 @@ result.stackcopy = i.stackcopy

result.scope = i.scope result.currSym = MinValue(column: 1, line: 1, kind: minSymbol, symVal: "") -proc formatError(sym: MinValue, message: string): string {.extern:"min_exported_symbol_$1".}= +proc formatError(sym: MinValue, message: string): string = if sym.filename == "": return "[$1]: $2" % [sym.symVal, message] else: return "$1($2,$3) [$4]: $5" % [sym.filename, $sym.line, $sym.column, sym.symVal, message] -proc formatTrace(sym: MinValue): string {.extern:"min_exported_symbol_$1".}= +proc formatTrace(sym: MinValue): string = if sym.filename == "": return "<native> in symbol: $1" % [sym.symVal] else:

@@ -128,11 +128,11 @@

proc error(i: In, message: string) = error(i.currSym.formatError(message)) -proc open*(i: In, stream:Stream, filename: string) {.extern:"min_exported_symbol_$1_2".}= +proc open*(i: In, stream:Stream, filename: string) = i.filename = filename i.parser.open(stream, filename) -proc close*(i: In) {.extern:"min_exported_symbol_$1_2".}= +proc close*(i: In) = i.parser.close(); proc push*(i: In, val: MinValue) {.gcsafe, extern:"min_exported_symbol_$1".}

@@ -197,7 +197,7 @@ i.push e

else: i.push(op.val) -proc dequote*(i: In, q: var MinValue) {.extern:"min_exported_symbol_$1".}= +proc dequote*(i: In, q: var MinValue) = if q.kind == minQuotation: i.withScope(): let qqval = deepCopy(q.qVal)

@@ -257,13 +257,13 @@ i.stack.add(v)

else: i.stack.add(val) -proc pop*(i: In): MinValue {.extern:"min_exported_symbol_$1".}= +proc pop*(i: In): MinValue = if i.stack.len > 0: return i.stack.pop else: raiseEmptyStack() -proc peek*(i: MinInterpreter): MinValue {.extern:"min_exported_symbol_$1".}= +proc peek*(i: MinInterpreter): MinValue = if i.stack.len > 0: return i.stack[i.stack.len-1] else:

@@ -410,9 +410,8 @@ result.objType = "module"

for key, value in i2.scope.symbols.pairs: result.scope.symbols[key] = value -proc parse*(i: In, s: string, name="<parse>"): MinValue {.extern:"min_exported_symbol_$1".}= +proc parse*(i: In, s: string, name="<parse>"): MinValue = return i.eval(s, name, true) -proc read*(i: In, s: string): MinValue {.extern:"min_exported_symbol_$1".}= +proc read*(i: In, s: string): MinValue = return i.load(s, true) -
M core/parser.nimcore/parser.nim

@@ -126,16 +126,16 @@ var CVARCOUNT = 0

# Helpers -proc raiseInvalid*(msg: string) {.extern:"min_exported_symbol_$1".}= +proc raiseInvalid*(msg: string) = raise MinInvalidError(msg: msg) -proc raiseUndefined*(msg: string) {.extern:"min_exported_symbol_$1".}= +proc raiseUndefined*(msg: string) = raise MinUndefinedError(msg: msg) -proc raiseOutOfBounds*(msg: string) {.extern:"min_exported_symbol_$1".}= +proc raiseOutOfBounds*(msg: string) = raise MinOutOfBoundsError(msg: msg) -proc raiseEmptyStack*() {.extern:"min_exported_symbol_$1".}= +proc raiseEmptyStack*() = raise MinEmptyStackError(msg: "Insufficient items on the stack") proc dVal*(v: MinValue): CritBitTree[MinOperator] {.inline, extern:"min_exported_symbol_$1".}=

@@ -173,14 +173,14 @@ "true",

"false" ] -proc newScope*(parent: ref MinScope, kind = minLangScope): MinScope {.extern:"min_exported_symbol_$1".}= +proc newScope*(parent: ref MinScope, kind = minLangScope): MinScope = result = MinScope(parent: parent, kind: kind) -proc newScopeRef*(parent: ref MinScope, kind = minLangScope): ref MinScope {.extern:"min_exported_symbol_$1".}= +proc newScopeRef*(parent: ref MinScope, kind = minLangScope): ref MinScope = new(result) result[] = newScope(parent, kind) -proc open*(my: var MinParser, input: Stream, filename: string) {.extern:"min_exported_symbol_$1".}= +proc open*(my: var MinParser, input: Stream, filename: string) = lexbase.open(my, input) my.filename = filename my.state = @[stateStart]

@@ -210,16 +210,16 @@

proc getFilename*(my: MinParser): string {.inline, extern:"min_exported_symbol_$1".}= result = my.filename -proc errorMsg*(my: MinParser, msg: string): string {.extern:"min_exported_symbol_$1".}= +proc errorMsg*(my: MinParser, msg: string): string = assert(my.kind == eMinError) result = "$1 [l:$2, c:$3] ERROR - $4" % [ my.filename, $getLine(my), $getColumn(my), msg] -proc errorMsg*(my: MinParser): string {.extern:"min_exported_symbol_$1_2".}= +proc errorMsg*(my: MinParser): string = assert(my.kind == eMinError) result = errorMsg(my, errorMessages[my.err]) -proc errorMsgExpected*(my: MinParser, e: string): string {.extern:"min_exported_symbol_$1".}= +proc errorMsgExpected*(my: MinParser, e: string): string = result = errorMsg(my, e & " expected") proc raiseParsing*(p: MinParser, msg: string) {.noinline, noreturn, extern:"min_exported_symbol_$1".}=

@@ -420,7 +420,7 @@ else:

break my.bufpos = pos -proc getToken*(my: var MinParser): MinTokenKind {.extern:"min_exported_symbol_$1".}= +proc getToken*(my: var MinParser): MinTokenKind = setLen(my.a, 0) skip(my) case my.buf[my.bufpos]

@@ -466,7 +466,7 @@ discard

my.token = result -proc next*(my: var MinParser) {.extern:"min_exported_symbol_$1".}= +proc next*(my: var MinParser) = var tk = getToken(my) var i = my.state.len-1 case my.state[i]

@@ -544,7 +544,7 @@ else:

my.kind = eMinError my.err = errExprExpected -proc eat(p: var MinParser, token: MinTokenKind) {.extern:"min_exported_symbol_$1".}= +proc eat(p: var MinParser, token: MinTokenKind) = if p.token == token: discard getToken(p) else: raiseParsing(p, tokToStr[token])

@@ -622,7 +622,7 @@ d = d & ";" & a.objType

d = d.strip & "}" return d -proc parseMinValue*(p: var MinParser, i: In): MinValue {.extern:"min_exported_symbol_$1".}= +proc parseMinValue*(p: var MinParser, i: In): MinValue = case p.token of tkNull: result = MinValue(kind: minNull)

@@ -685,7 +685,7 @@ let err = "Undefined or invalid value: "&p.a

raiseUndefined(p, err) result.filename = p.filename -proc compileMinValue*(p: var MinParser, i: In, push = true, indent = ""): seq[string] {.extern:"min_exported_symbol_$1".}= +proc compileMinValue*(p: var MinParser, i: In, push = true, indent = ""): seq[string] = var op = indent if push: op = indent&"i.push "

@@ -763,47 +763,47 @@ discard getToken(p)

else: raiseUndefined(p, "Undefined value: '"&p.a&"'") -proc print*(a: MinValue) {.extern:"min_exported_symbol_$1".}= +proc print*(a: MinValue) = stdout.write($$a) # Predicates -proc isNull*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isNull*(s: MinValue): bool = return s.kind == minNull -proc isSymbol*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isSymbol*(s: MinValue): bool = return s.kind == minSymbol -proc isQuotation*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isQuotation*(s: MinValue): bool = return s.kind == minQuotation -proc isString*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isString*(s: MinValue): bool = return s.kind == minString -proc isFloat*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isFloat*(s: MinValue): bool = return s.kind == minFloat -proc isInt*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isInt*(s: MinValue): bool = return s.kind == minInt -proc isNumber*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isNumber*(s: MinValue): bool = return s.kind == minInt or s.kind == minFloat proc isBool*(s: MinValue): bool = return s.kind == minBool -proc isStringLike*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isStringLike*(s: MinValue): bool = 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".}= +proc isDictionary*(q: MinValue): bool = return q.kind == minDictionary -proc isTypedDictionary*(q: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc isTypedDictionary*(q: MinValue): bool = if q.isDictionary: return q.objType != "" return false -proc isTypedDictionary*(q: MinValue, t: string): bool {.extern:"min_exported_symbol_$1_2".}= +proc isTypedDictionary*(q: MinValue, t: string): bool = if q.isTypedDictionary: return q.objType == t return false

@@ -861,4 +861,4 @@ return a.objType == b.objType

else: return false else: - return false + return false
M core/scope.nimcore/scope.nim

@@ -4,14 +4,14 @@ critbits

import parser -proc copy*(s: ref MinScope): ref MinScope {.extern:"min_exported_symbol_$1".}= +proc copy*(s: ref MinScope): ref MinScope = var scope = newScope(s.parent) scope.symbols = s.symbols scope.sigils = s.sigils new(result) result[] = scope -proc getSymbol*(scope: ref MinScope, key: string, acc=0): MinOperator {.extern:"min_exported_symbol_$1".}= +proc getSymbol*(scope: ref MinScope, key: string, acc=0): MinOperator = if scope.symbols.hasKey(key): return scope.symbols[key] else:

@@ -19,7 +19,7 @@ if scope.parent.isNil:

raiseUndefined("Symbol '$1' not found." % key) return scope.parent.getSymbol(key, acc + 1) -proc hasSymbol*(scope: ref MinScope, key: string): bool {.extern:"min_exported_symbol_$1".}= +proc hasSymbol*(scope: ref MinScope, key: string): bool = if scope.isNil: return false elif scope.symbols.hasKey(key):

@@ -50,7 +50,7 @@ # Go up the scope chain and attempt to find the symbol

if not scope.parent.isNil: result = scope.parent.setSymbol(key, value) -proc getSigil*(scope: ref MinScope, key: string): MinOperator {.extern:"min_exported_symbol_$1".}= +proc getSigil*(scope: ref MinScope, key: string): MinOperator = if scope.sigils.hasKey(key): return scope.sigils[key] elif not scope.parent.isNil:

@@ -58,7 +58,7 @@ return scope.parent.getSigil(key)

else: raiseUndefined("Sigil '$1' not found." % key) -proc hasSigil*(scope: ref MinScope, key: string): bool {.extern:"min_exported_symbol_$1".}= +proc hasSigil*(scope: ref MinScope, key: string): bool = if scope.isNil: return false elif scope.sigils.hasKey(key):

@@ -89,8 +89,8 @@ # Go up the scope chain and attempt to find the sigil

if not scope.parent.isNil: result = scope.parent.setSymbol(key, value) -proc previous*(scope: ref MinScope): ref MinScope {.extern:"min_exported_symbol_$1".}= +proc previous*(scope: ref MinScope): ref MinScope = if scope.parent.isNil: return scope else: - return scope.parent + return scope.parent
M core/utils.nimcore/utils.nim

@@ -14,24 +14,24 @@ json

# Library methods -proc define*(i: In): ref MinScope {.extern:"min_exported_symbol_$1".}= +proc define*(i: In): ref MinScope = var scope = newScopeRef(i.scope, minNativeScope) scope.parent = i.scope return scope -proc symbol*(scope: ref MinScope, sym: string, p: MinOperatorProc) {.extern:"min_exported_symbol_$1".}= +proc symbol*(scope: ref MinScope, sym: string, p: MinOperatorProc) = scope.symbols[sym] = MinOperator(prc: p, kind: minProcOp, sealed: true) -proc symbol*(scope: ref MinScope, sym: string, v: MinValue) {.extern:"min_exported_symbol_$1_2".}= +proc symbol*(scope: ref MinScope, sym: string, v: MinValue) = scope.symbols[sym] = MinOperator(val: v, kind: minValOp, sealed: true) -proc sigil*(scope: ref MinScope, sym: string, p: MinOperatorProc) {.extern:"min_exported_symbol_$1".}= +proc sigil*(scope: ref MinScope, sym: string, p: MinOperatorProc) = scope.sigils[sym] = MinOperator(prc: p, kind: minProcOp, sealed: true) -proc sigil*(scope: ref MinScope, sym: string, v: MinValue) {.extern:"min_exported_symbol_$1_2".}= +proc sigil*(scope: ref MinScope, sym: string, v: MinValue) = scope.sigils[sym] = MinOperator(val: v, kind: minValOp, sealed: true) -proc finalize*(scope: ref MinScope, name: string = "") {.extern:"min_exported_symbol_$1".}= +proc finalize*(scope: ref MinScope, name: string = "") = var mdl = newDict(scope) mdl.scope = scope mdl.objType = "module"

@@ -44,26 +44,26 @@ scope.previous.symbols[name] = MinOperator(kind: minProcOp, prc: op)

# Dictionary Methods -proc dget*(i: In, q: MinValue, s: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= +proc dget*(i: In, q: MinValue, s: MinValue): MinValue = if not q.isDictionary: raiseInvalid("Value is not a dictionary") if q.dVal[s.getString].kind == minProcOp: raiseInvalid("Key '$1' is set to a native value that cannot be retrieved." % [s.getString]) result = q.dVal[s.getString].val -proc dget*(i: In, q: MinValue, s: string): MinValue {.extern:"min_exported_symbol_$1_2".}= +proc dget*(i: In, q: MinValue, s: string): MinValue = if not q.isDictionary: raiseInvalid("Value is not a dictionary") if q.dVal[s].kind == minProcOp: raiseInvalid("Key $1 is set to a native value that cannot be retrieved." % [s]) result = q.dVal[s].val -proc dhas*(q: MinValue, s: MinValue): bool {.extern:"min_exported_symbol_$1".}= +proc dhas*(q: MinValue, s: MinValue): bool = if not q.isDictionary: raiseInvalid("Value is not a dictionary") return q.dVal.contains(s.getString) -proc dhas*(q: MinValue, s: string): bool {.extern:"min_exported_symbol_$1_2".}= +proc dhas*(q: MinValue, s: string): bool = if not q.isDictionary: raiseInvalid("Value is not a dictionary") return q.dVal.contains(s)

@@ -94,14 +94,14 @@ var q = m

p.scope.symbols[s] = MinOperator(kind: minValOp, val: q, sealed: false) return p -proc keys*(i: In, q: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= +proc keys*(i: In, q: MinValue): MinValue = # Assumes q is a dictionary var r = newSeq[MinValue](0) for i in q.dVal.keys: r.add newVal(i) return r.newVal -proc values*(i: In, q: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= +proc values*(i: In, q: MinValue): MinValue = # Assumes q is a dictionary var r = newSeq[MinValue](0) for item in q.dVal.values:

@@ -110,7 +110,7 @@ raiseInvalid("Dictionary contains native values that cannot be accessed.")

r.add item.val return r.newVal -proc pairs*(i: In, q: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= +proc pairs*(i: In, q: MinValue): MinValue = # Assumes q is a dictionary var r = newSeq[MinValue](0) for key, value in q.dVal.pairs:

@@ -124,7 +124,7 @@ when not defined(mini):

# JSON interop - proc `%`*(i: In, a: MinValue): JsonNode {.extern:"min_exported_symbol_percent_2".}= + proc `%`*(i: In, a: MinValue): JsonNode = case a.kind: of minBool: return %a.boolVal

@@ -147,7 +147,7 @@ result = newJObject()

for it in a.dVal.pairs: result[it.key] = i%i.dget(a, it.key) - proc fromJson*(i: In, json: JsonNode): MinValue {.extern:"min_exported_symbol_$1".}= + proc fromJson*(i: In, json: JsonNode): MinValue = case json.kind: of JNull: result = newNull()

@@ -176,7 +176,7 @@ return res.newVal

# Validators -proc validate(value: MinValue, t: string): bool {.extern:"min_exported_symbol_$1".}= +proc validate(value: MinValue, t: string): bool = case t: of "bool": return value.isBool

@@ -208,7 +208,7 @@ if value.isTypedDictionary(split[1]):

return true return false -proc expect*(i: var MinInterpreter, elements: varargs[string]): seq[MinValue] {.extern:"min_exported_symbol_$1".}= +proc expect*(i: var MinInterpreter, elements: varargs[string]): seq[MinValue] = let stack = elements.reverse.join(" ") let sym = i.currSym.getString var valid = newSeq[string](0)

@@ -236,7 +236,7 @@ elif not validate(value, element):

raiseInvalid(message(value.typeName)) valid.add element -proc reqQuotationOfQuotations*(i: var MinInterpreter, a: var MinValue) {.extern:"min_exported_symbol_$1".}= +proc reqQuotationOfQuotations*(i: var MinInterpreter, a: var MinValue) = a = i.pop if not a.isQuotation: raiseInvalid("A quotation is required on the stack")

@@ -244,7 +244,7 @@ for s in a.qVal:

if not s.isQuotation: raiseInvalid("A quotation of quotations is required on the stack") -proc reqQuotationOfNumbers*(i: var MinInterpreter, a: var MinValue) {.extern:"min_exported_symbol_$1".}= +proc reqQuotationOfNumbers*(i: var MinInterpreter, a: var MinValue) = a = i.pop if not a.isQuotation: raiseInvalid("A quotation is required on the stack")

@@ -252,7 +252,7 @@ for s in a.qVal:

if not s.isNumber: raiseInvalid("A quotation of numbers is required on the stack") -proc reqQuotationOfSymbols*(i: var MinInterpreter, a: var MinValue) {.extern:"min_exported_symbol_$1".}= +proc reqQuotationOfSymbols*(i: var MinInterpreter, a: var MinValue) = a = i.pop if not a.isQuotation: raiseInvalid("A quotation is required on the stack")

@@ -260,19 +260,19 @@ for s in a.qVal:

if not s.isSymbol: raiseInvalid("A quotation of symbols is required on the stack") -proc reqTwoNumbersOrStrings*(i: var MinInterpreter, a, b: var MinValue) {.extern:"min_exported_symbol_$1".}= +proc reqTwoNumbersOrStrings*(i: var MinInterpreter, a, b: var MinValue) = a = i.pop b = i.pop if not (a.isString and b.isString or a.isNumber and b.isNumber): raiseInvalid("Two numbers or two strings are required on the stack") -proc reqStringOrQuotation*(i: var MinInterpreter, a: var MinValue) {.extern:"min_exported_symbol_$1".}= +proc reqStringOrQuotation*(i: var MinInterpreter, a: var MinValue) = a = i.pop if not a.isQuotation and not a.isString: raiseInvalid("A quotation or a string is required on the stack") -proc reqTwoQuotationsOrStrings*(i: var MinInterpreter, a, b: var MinValue) {.extern:"min_exported_symbol_$1".}= +proc reqTwoQuotationsOrStrings*(i: var MinInterpreter, a, b: var MinValue) = a = i.pop b = i.pop if not (a.isQuotation and b.isQuotation or a.isString and b.isString): - raiseInvalid("Two quotations or two strings are required on the stack") + raiseInvalid("Two quotations or two strings are required on the stack")
M core/value.nimcore/value.nim

@@ -1,7 +1,7 @@

import parser -proc typeName*(v: MinValue): string {.extern:"min_exported_symbol_$1".}= +proc typeName*(v: MinValue): string = case v.kind: of minInt: return "int"

@@ -25,36 +25,36 @@ return "bool"

# Constructors -proc newNull*(): MinValue {.extern:"min_exported_symbol_$1".}= +proc newNull*(): MinValue = return MinValue(kind: minNull) -proc newVal*(s: string): MinValue {.extern:"min_exported_symbol_$1".}= +proc newVal*(s: string): MinValue = return MinValue(kind: minString, strVal: s) -proc newVal*(s: cstring): MinValue {.extern:"min_exported_symbol_$1_2".}= +proc newVal*(s: cstring): MinValue = return MinValue(kind: minString, strVal: $s) -proc newVal*(q: seq[MinValue]): MinValue {.extern:"min_exported_symbol_$1_3".}= +proc newVal*(q: seq[MinValue]): MinValue = return MinValue(kind: minQuotation, qVal: q) -proc newVal*(i: BiggestInt): MinValue {.extern:"min_exported_symbol_$1_4".}= +proc newVal*(i: BiggestInt): MinValue = return MinValue(kind: minInt, intVal: i) -proc newVal*(f: BiggestFloat): MinValue {.extern:"min_exported_symbol_$1_5".}= +proc newVal*(f: BiggestFloat): MinValue = return MinValue(kind: minFloat, floatVal: f) -proc newVal*(s: bool): MinValue {.extern:"min_exported_symbol_$1_6".}= +proc newVal*(s: bool): MinValue = return MinValue(kind: minBool, boolVal: s) -proc newDict*(parentScope: ref MinScope): MinValue {.extern:"min_exported_symbol_$1".}= +proc newDict*(parentScope: ref MinScope): MinValue = return MinValue(kind: minDictionary, scope: newScopeRef(parentScope)) -proc newSym*(s: string): MinValue {.extern:"min_exported_symbol_$1".}= +proc newSym*(s: string): MinValue = return MinValue(kind: minSymbol, symVal: s) # Get string value from string or quoted symbol -proc getFloat*(v: MinValue): float {.extern:"min_exported_symbol_$1".}= +proc getFloat*(v: MinValue): float = if v.isInt: return v.intVal.float elif v.isFloat:

@@ -62,7 +62,7 @@ return v.floatVal

else: raiseInvalid("Value is not a number") -proc getString*(v: MinValue): string {.extern:"min_exported_symbol_$1".}= +proc getString*(v: MinValue): string = if v.isSymbol: return v.symVal elif v.isString:

@@ -74,4 +74,4 @@ let sym = v.qVal[0]

if sym.isSymbol: return sym.symVal else: - raiseInvalid("Quotation is not a quoted symbol") + raiseInvalid("Quotation is not a quoted symbol")
M min.nimmin.nim

@@ -12,7 +12,6 @@ import

json, os, algorithm, - dynlib, logging, packages/niftylogger import

@@ -142,28 +141,6 @@ dir = getCurrentDir()

return toSeq(walkDir(dir, true)).filterIt(it.path.toLowerAscii.startsWith(f.toLowerAscii)).mapIt("\"$1" % [it.path.replace("\\", "/")]) return symbols - type - LibProc = proc(i: In) {.nimcall.} - - proc dynLib*(i: In) = - discard MINLIBS.existsOrCreateDir - for library in walkFiles(MINLIBS & "/*"): - var modname = library.splitFile.name - var libfile = library.splitFile.name & library.splitFile.ext - if modname.len > 3 and modname[0..2] == "lib": - modname = modname[3..modname.len-1] - let dll = library.loadLib() - if dll != nil: - let modsym = dll.symAddr(modname) - if modsym != nil: - let modproc = cast[LibProc](dll.symAddr(modname)) - i.modproc() - logging.info("[$1] Dynamic module loaded successfully: $2" % [libfile, modname]) - else: - logging.warn("[$1] Library does not contain symbol $2" % [libfile, modname]) - else: - logging.warn("Unable to load dynamic library: " & libfile) - proc stdLib*(i: In) = when not defined(mini):

@@ -207,8 +184,6 @@ i.eval MINRC.readFile()

proc interpret*(i: In, s: Stream) = i.stdLib() - when not defined(mini): - i.dynLib() i.open(s, i.filename) discard i.parser.getToken() try:

@@ -356,8 +331,6 @@ echo " $1" % [$i.stack[i.stack.len - 1]]

proc minSimpleRepl*(i: var MinInterpreter) = i.stdLib() - when not defined(mini): - i.dynLib() var s = newStringStream("") i.open(s, "<repl>") var line: string

@@ -377,7 +350,6 @@ when not defined(mini):

proc minRepl*(i: var MinInterpreter) = i.stdLib() - i.dynLib() var s = newStringStream("") i.open(s, "<repl>") var line: string
M min.ymlmin.yml

@@ -1,5 +1,5 @@

author: Fabio Cevasco description: A tiny concatenative programming language and shell. -id: 35718567 +id: 35746169 name: min -version: 0.26.0+version: 0.27.0
D mindyn.nim

@@ -1,222 +0,0 @@

-{.pragma: rtl, exportc, dynlib, cdecl.} -# Everything below here is to interface with the main program -# Import for the missing types (Look into importing just type definitions) -import - lexbase, - streams, - critbits, - json, - os - -type - MinTokenKind* = enum - tkError, - tkEof, - tkString, - tkInt, - tkFloat, - tkBracketLe, - tkBracketRi, - tkSymbol, - tkTrue, - tkFalse - MinKind* = enum - minInt, - minFloat, - minQuotation, - minString, - minSymbol, - minBool - MinEventKind* = enum ## enumeration of all events that may occur when parsing - eMinError, ## an error ocurred during parsing - eMinEof, ## end of file reached - eMinString, ## a string literal - eMinInt, ## an integer literal - eMinFloat, ## a float literal - eMinQuotationStart, ## start of an array: the ``(`` token - eMinQuotationEnd ## start of an array: the ``)`` token - MinParserError* = enum ## enumeration that lists all errors that can occur - errNone, ## no error - errInvalidToken, ## invalid token - errStringExpected, ## string expected - errBracketRiExpected, ## ``)`` expected - errQuoteExpected, ## ``"`` or ``'`` expected - errEOC_Expected, ## ``*/`` expected - errEofExpected, ## EOF expected - errExprExpected - MinParserState* = enum - stateEof, - stateStart, - stateQuotation, - stateExpectValue - MinParser* = object of BaseLexer - a*: string - token*: MinTokenKind - state*: seq[MinParserState] - kind*: MinEventKind - err*: MinParserError - filename*: string - MinValue* = ref MinValueObject - MinValueObject* = object - line*: int - column*: int - filename*: string - case kind*: MinKind - of minInt: intVal*: BiggestInt - of minFloat: floatVal*: BiggestFloat - of minQuotation: - qVal*: seq[MinValue] - scope*: ref MinScope - of minString: strVal*: string - of minSymbol: symVal*: string - of minBool: boolVal*: bool - MinScope* = object - symbols*: CritBitTree[MinOperator] - sigils*: CritBitTree[MinOperator] - parent*: ref MinScope - name*: string - stack*: MinStack - MinOperatorProc* = proc (i: In) {.closure.} - MinOperatorKind* = enum - minProcOp - minValOp - MinOperator* = object - sealed*: bool - case kind*: MinOperatorKind - of minProcOp: - prc*: MinOperatorProc - of minValOp: - val*: MinValue - MinStack* = seq[MinValue] - In* = var MinInterpreter - MinInterpreter* = object - stack*: MinStack - trace*: MinStack - stackcopy*: MinStack - pwd*: string - scope*: ref MinScope - parser*: MinParser - currSym*: MinValue - filename*: string - evaluating*: bool - MinParsingError* = ref object of ValueError - MinUndefinedError* = ref object of ValueError - MinEmptyStackError* = ref object of ValueError - MinInvalidError* = ref object of ValueError - MinOutOfBoundsError* = ref object of ValueError - -# parser.nim -proc raiseInvalid(msg: string) {.importc, extern:"min_exported_symbol_$1".} -proc raiseUndefined(msg: string) {.importc, extern:"min_exported_symbol_$1".} -proc raiseOutOfBounds(msg: string) {.importc, extern:"min_exported_symbol_$1".} -proc raiseEmptyStack() {.importc, extern:"min_exported_symbol_$1".} -proc newScope(parent: ref MinScope): MinScope {.importc, extern:"min_exported_symbol_$1".} -proc newScopeRef(parent: ref MinScope): ref MinScope {.importc, extern:"min_exported_symbol_$1".} -proc open(my: var MinParser, input: Stream, filename: string) {.importc, extern:"min_exported_symbol_$1".} -proc close(my: var MinParser) {.importc, extern:"min_exported_symbol_$1".} -proc getInt(my: MinParser): int {.importc, extern:"min_exported_symbol_$1".} -proc getFloat(my: MinParser): float {.importc, extern:"min_exported_symbol_$1".} -proc kind(my: MinParser): MinEventKind {.importc, extern:"min_exported_symbol_$1".} -proc getColumn(my: MinParser): int {.importc, extern:"min_exported_symbol_$1".} -proc getLine(my: MinParser): int {.importc, extern:"min_exported_symbol_$1".} -proc getFilename(my: MinParser): string {.importc, extern:"min_exported_symbol_$1".} -proc errorMsg(my: MinParser, msg: string): string {.importc, extern:"min_exported_symbol_$1".} -proc errorMsg(my: MinParser): string {.importc, extern:"min_exported_symbol_$1_2".} -proc errorMsgExpected(my: MinParser, e: string): string {.importc, extern:"min_exported_symbol_$1".} -proc raiseParsing(p: MinParser, msg: string) {.importc, extern:"min_exported_symbol_$1".} -proc raiseUndefined(p:MinParser, msg: string) {.importc, extern:"min_exported_symbol_$1_2".} -proc getToken(my: var MinParser): MinTokenKind {.importc, extern:"min_exported_symbol_$1".} -proc next(my: var MinParser) {.importc, extern:"min_exported_symbol_$1".} -proc eat(p: var MinParser, token: MinTokenKind) {.importc, extern:"min_exported_symbol_$1".} -proc parseMinValue(p: var MinParser, i: In): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc `$`(a: MinValue): string {.importc, extern:"min_exported_symbol_$1".} -proc `$$`(a: MinValue): string {.importc, extern:"min_exported_symbol_$1".} -proc print(a: MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc `==`(a: MinValue, b: MinValue): bool {.importc, extern:"min_exported_symbol_eqeq".} - -# value.nim -proc typeName*(v: MinValue): string {.importc, extern:"min_exported_symbol_$1".} -proc isSymbol*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isQuotation*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isString*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isFloat*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isInt*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isNumber*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isBool*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isStringLike*(s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isDictionary*(q: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc isTypedDictionary*(q: MinValue): bool {.extern:"min_exported_symbol_$1".}= -proc isTypedDictionary*(q: MinValue, t: string): bool {.extern:"min_exported_symbol_$1_2".}= -proc newVal*(s: string): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc newVal*(s: cstring): MinValue {.importc, extern:"min_exported_symbol_$1_2".} -proc newVal*(q: seq[MinValue], parentScope: ref MinScope): MinValue {.importc, extern:"min_exported_symbol_$1_3".} -proc newVal*(s: BiggestInt): MinValue {.importc, extern:"min_exported_symbol_$1_4".} -proc newVal*(s: BiggestFloat): MinValue {.importc, extern:"min_exported_symbol_$1_5".} -proc newVal*(s: bool): MinValue {.importc, extern:"min_exported_symbol_$1_6".} -proc newSym*(s: string): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc getFloat*(v: MinValue): float {.importc, extern:"min_exported_symbol_$1".} -proc getString*(v: MinValue): string {.importc, extern:"min_exported_symbol_$1".} - -# utils.nim -proc define*(i: In): ref MinScope {.importc, extern:"min_exported_symbol_$1".} -proc symbol*(scope: ref MinScope, sym: string, p: MinOperatorProc) {.importc, extern:"min_exported_symbol_$1".} -proc symbol*(scope: ref MinScope, sym: string, v: MinValue) {.importc, extern:"min_exported_symbol_$1_2".} -proc sigil*(scope: ref MinScope, sym: string, p: MinOperatorProc) {.importc, extern:"min_exported_symbol_$1".} -proc sigil*(scope: ref MinScope, sym: string, v: MinValue) {.importc, extern:"min_exported_symbol_$1_2".} -proc finalize*(scope: ref MinScope, name: string) {.importc, extern:"min_exported_symbol_$1".} -proc dget*(q: MinValue, s: MinValue): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc dhas*(q: MinValue, s: MinValue): bool {.importc, extern:"min_exported_symbol_$1".} -proc ddel*(i: In, p: MinValue, s: MinValue): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc dset*(i: In, p: MinValue, s: MinValue, m: MinValue): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc keys*(i: In, q: MinValue): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc values*(i: In, q: MinValue): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc `%`*(a: MinValue): JsonNode {.importc, extern:"min_exported_symbol_percent".} -proc fromJson*(i: In, json: JsonNode): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc reverse[T](xs: openarray[T]): seq[T] {.importc, extern:"min_exported_symbol_$1".} -proc expect*(i: var MinInterpreter, elements: varargs[string]): seq[MinValue] {.importc, extern:"min_exported_symbol_$1".} -proc reqQuotationOfQuotations*(i: var MinInterpreter, a: var MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc reqQuotationOfNumbers*(i: var MinInterpreter, a: var MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc reqQuotationOfSymbols*(i: var MinInterpreter, a: var MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc reqTwoNumbersOrStrings*(i: var MinInterpreter, a, b: var MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc reqStringOrQuotation*(i: var MinInterpreter, a: var MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc reqTwoQuotationsOrStrings*(i: var MinInterpreter, a, b: var MinValue) {.importc, extern:"min_exported_symbol_$1".} - -# scope.nim -proc copy*(s: ref MinScope): ref MinScope {.importc, extern:"min_exported_symbol_$1".} -proc getSymbol*(scope: ref MinScope, key: string): MinOperator {.importc, extern:"min_exported_symbol_$1".} -proc hasSymbol*(scope: ref MinScope, key: string): bool {.importc, extern:"min_exported_symbol_$1".} -proc delSymbol*(scope: ref MinScope, key: string): bool {.importc, extern:"min_exported_symbol_$1".} -proc setSymbol*(scope: ref MinScope, key: string, value: MinOperator, override: bool): bool {.importc, extern:"min_exported_symbol_$1".} -proc getSigil*(scope: ref MinScope, key: string): MinOperator {.importc, extern:"min_exported_symbol_$1".} -proc hasSigil*(scope: ref MinScope, key: string): bool {.importc, extern:"min_exported_symbol_$1".} -proc previous*(scope: ref MinScope): ref MinScope {.importc, extern:"min_exported_symbol_$1".} - -# interpreter.nim -proc raiseRuntime*(msg: string, qVal: var seq[MinValue]) {.importc, extern:"min_exported_symbol_$1".} -proc dump*(i: MinInterpreter): string {.importc, extern:"min_exported_symbol_$1".} -proc debug*(i: In, value: MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc debug*(i: In, value: string) {.importc, extern:"min_exported_symbol_$1_2".} -proc newMinInterpreter*(filename: string): MinInterpreter {.importc, extern:"min_exported_symbol_$1".} -proc copy*(i: MinInterpreter, filename: string): MinInterpreter {.importc, extern:"min_exported_symbol_$1_2".} -proc formatError(sym: MinValue, message: string): string {.importc, extern:"min_exported_symbol_$1".} -proc formatTrace(sym: MinValue): string {.importc, extern:"min_exported_symbol_$1".} -proc stackTrace(i: In) {.importc, extern:"min_exported_symbol_$1".} -proc error(i: In, message: string) {.importc, extern:"min_exported_symbol_$1".} -proc open*(i: In, stream:Stream, filename: string) {.importc, extern:"min_exported_symbol_$1_2".} -proc close*(i: In) {.importc, extern:"min_exported_symbol_$1_2".} -proc apply*(i: In, op: MinOperator) {.importc, extern:"min_exported_symbol_$1".} -proc push*(i: In, val: MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc dequote*(i: In, q: var MinValue) {.importc, extern:"min_exported_symbol_$1".} -proc apply*(i: In, q: var MinValue) {.importc, extern:"min_exported_symbol_$1_2".} -proc pop*(i: In): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc peek*(i: MinInterpreter): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc interpret*(i: In): MinValue {.importc, discardable, extern:"min_exported_symbol_$1".} -proc eval*(i: In, s: string, name: string, parseOnly: bool) {.importc, discardable, extern:"min_exported_symbol_$1".} -proc load*(i: In, s: string, parseOnly: bool): MinValue {.importc, discardable, extern:"min_exported_symbol_$1".} -proc parse*(i: In, s: string, name: string): MinValue {.importc, extern:"min_exported_symbol_$1".} -proc read*(i: In, s: string): MinValue {.importc, extern:"min_exported_symbol_$1".} - -# fileutils.nim -proc filetype*(p: PathComponent): string {.importc, extern:"min_exported_symbol_$1".} -proc unixPermissions*(s: set[FilePermission]): int {.importc, extern:"min_exported_symbol_$1".} -proc toFilePermissions*(p: BiggestInt): set[FilePermission] {.importc, extern:"min_exported_symbol_$1".}
M next-release.mdnext-release.md

@@ -1,10 +1,1 @@

-* Added **encode-url**, **decode-url**, **parse-url** symbols. -* Added **dstore** module providing support for simple, persistent, in-memory JSON stores. -* Added **require** symbol to read a min file and automatically create a module containing all symbols defined in the file. -* Added **invoke** symbol (and **\*** sigil) to easily call a symbol defined in a module or dictionary, e.g. `*mymodule/mymethod`, or `*dict1/a/b`. -* Fixed library installation via nimble -* Fixed error handling and stack trace for **start-server** symbol. -* Added the possibility to bundle assets in a compiled min program by specifying tbe **-a** (or **--asset-path**) option. -* Added **expect-empty-stack** (**=-=**) symbol. -* Added **null** data type, added **null?** symbol. -* Added **reverse-expect-dequote** (**\-\-**) symbol. +* **REMOVED** support for creating dynamic libraries (it never worked properly anyway)
M site/contents/learn-extending.mdsite/contents/learn-extending.md

@@ -6,11 +6,11 @@ {@ _defs_.md || 0 @}

min provides a fairly complete standard library with many useful modules. However, you may feel the need to extend min in order to perform more specialized tasks. -In such situations, you basically have three options: +In such situations, you basically have the following options: -* Implement new min modules in min -* Embed min in your [Nim](https://nim-lang.org) program -* Implemet min modules as dynamic libraries in Nim +* Implementing new min modules using min itself +* Specifying your custom prelude program +* Embedding min in your [Nim](https://nim-lang.org) program ## Implementing new min modules using min itself

@@ -123,74 +123,3 @@ > Tip

> > For more information on how to create new modules with Nim, have a look in the [lib folder](https://github.com/h3rald/min/tree/master/lib) of the min repository, which contains all the min modules included in the standard library. - -## Implementing min modules as dynamic libraries - -> %warning% -> Warning -> -> This technique is currently highly experimental, it has not been tested extensively and it may not even work properly. - -If you just want to add a new module to min providing functinalities that cannot be built natively with min operators, you can also implement a min module in Nim and compile it to a dynamic library which can be linked dynamically when min is started. - -In order to do this, you don't even need to download the whole min source code, you just need to download the [mindyn.nim](https://github.com/h3rald/min/blob/master/mindyn.nim) file and import it in your Nim program. - -The following code shows how to create a simple min module called *dyntest* containing only a single operator *dynplus*, which essentially returns the sum of two numbers: - -``` -import mindyn - -proc dyntest*(i: In) {.dynlib, exportc.} = - - let def = i.define() - - def.symbol("dynplus") do (i: In): - let vals = i.expect("num", "num") - let a = vals[0] - let b = vals[1] - if a.isInt: - if b.isInt: - i.push newVal(a.intVal + b.intVal) - else: - i.push newVal(a.intVal.float + b.floatVal) - else: - if b.isFloat: - i.push newVal(a.floatVal + b.floatVal) - else: - i.push newVal(a.floatVal + b.intVal.float) - - def.finalize("dyntest") -``` - -Note that the `mindym.nim` file contains the signatures of all the `proc`s that are commonly used to define min modules, but not their implementation. Such `proc`s will become available at run time when the dynamic library is linked to the min executable. - -You can compile the following library by running the following command: - -> %min-terminal% -> [$](class:prompt) nim c \-\-app:lib -d:release \ -> \-\-noMain dyntest.nim - -If you are using [clang](https://clang.llvm.org/) to compile Nim code, you may need to run the following command instead: - -> %min-terminal% -> [$](class:prompt) nim c \-\-app:lib -d:release \-\-noMain \ -> -l:&#34;-undefined dynamic\_lookup&#34; dyntest.nim - -Now you should have a `libdyntest.so|dyn|dll` file. To make min load it and link it automatically when it starts, just run: - -> %min-terminal% -> [$](class:prompt) min \-\-install:libdyntest.dyn - -This command will copy the library file to `$HOME/.minlibs/` (`%HOMEPATH%\.minlibs\` on Windows). min looks for dynamic libraries in this folder when it starts. - -> %note% -> Notes -> -> * The dynamic library file must have the same name as the module it defines (*dyntest* in this case). -> * At startup, min links all your installed dynamic libraries but does not import the modules automatically. - -If you wish to uninstall the library, run the following command instead: - -> %min-terminal% -> [$](class:prompt) min \-\-uninstall:libdyntest.dyn -
M site/settings.jsonsite/settings.json

@@ -6,5 +6,5 @@ "rules": "rules.min",

"temp": "temp", "templates": "templates", "title": "min language", - "version": "0.26.0" + "version": "0.27.0" }