all repos — min @ 18c54de95aef289bc18a53c437df743310f75622

A small but practical concatenative programming language.

Implemented null data type.
h3rald h3rald@h3rald.com
Thu, 24 Dec 2020 21:58:20 +0000
commit

18c54de95aef289bc18a53c437df743310f75622

parent

908d09e983e328d669bc4b1d72fbe846351c3a59

M core/parser.nimcore/parser.nim

@@ -21,6 +21,7 @@ tkBracketRi,

tkBraceLe, tkBraceRi, tkSymbol, + tkNull, tkTrue, tkFalse MinKind* = enum

@@ -30,6 +31,7 @@ minQuotation,

minDictionary, minString, minSymbol, + minNull, minBool MinEventKind* = enum ## enumeration of all events that may occur when parsing eMinError, ## an error ocurred during parsing

@@ -70,6 +72,7 @@ line*: int

column*: int filename*: string case kind*: MinKind + of minNull: discard of minInt: intVal*: BiggestInt of minFloat: floatVal*: BiggestFloat of minDictionary:

@@ -165,6 +168,7 @@ ")",

"{", "}", "symbol", + "null", "true", "false" ]

@@ -454,6 +458,7 @@ result = tkEof

else: result = parseSymbol(my) case my.a + of "null": result = tkNull of "true": result = tkTrue of "false": result = tkFalse else:

@@ -545,6 +550,8 @@ else: raiseParsing(p, tokToStr[token])

proc `$`*(a: MinValue): string {.inline, extern:"min_exported_symbol_$1".}= case a.kind: + of minNull: + return "null" of minBool: return $a.boolVal of minSymbol:

@@ -580,6 +587,8 @@ return d

proc `$$`*(a: MinValue): string {.inline, extern:"min_exported_symbol_$1".}= case a.kind: + of minNull: + return "null" of minBool: return $a.boolVal of minSymbol:

@@ -615,6 +624,9 @@ return d

proc parseMinValue*(p: var MinParser, i: In): MinValue {.extern:"min_exported_symbol_$1".}= case p.token + of tkNull: + result = MinValue(kind: minNull) + discard getToken(p) of tkTrue: result = MinValue(kind: minBool, boolVal: true) discard getToken(p)

@@ -679,6 +691,8 @@ if push:

op = indent&"i.push " result = newSeq[string](0) case p.token + of tkNull: + result = @[op&"MinValue(kind: minNull)"] of tkTrue: result = @[op&"MinValue(kind: minBool, boolVal: true)"] discard getToken(p)

@@ -754,6 +768,9 @@ stdout.write($$a)

# Predicates +proc isNull*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= + return s.kind == minNull + proc isSymbol*(s: MinValue): bool {.extern:"min_exported_symbol_$1".}= return s.kind == minSymbol

@@ -809,6 +826,8 @@ if a.kind == minString:

return a.strVal == b.strVal elif a.kind == minBool: return a.boolVal == b.boolVal + elif a.kind == minNull: + return true elif a.kind == minQuotation: if a.qVal.len == b.qVal.len: var c = 0
M core/utils.nimcore/utils.nim

@@ -128,6 +128,8 @@ proc `%`*(i: In, a: MinValue): JsonNode {.extern:"min_exported_symbol_percent_2".}=

case a.kind: of minBool: return %a.boolVal + of minNull: + return newJNull() of minSymbol: return %(";sym:$1" % [a.getstring]) of minString:

@@ -148,7 +150,7 @@

proc fromJson*(i: In, json: JsonNode): MinValue {.extern:"min_exported_symbol_$1".}= case json.kind: of JNull: - result = newSeq[MinValue](0).newVal + result = newNull() of JBool: result = json.getBool.newVal of JInt:

@@ -178,6 +180,8 @@ proc validate(value: MinValue, t: string): bool {.extern:"min_exported_symbol_$1".}=

case t: of "bool": return value.isBool + of "null": + return value.isNull of "int": return value.isInt of "num":
M core/value.nimcore/value.nim

@@ -1,72 +1,77 @@

-import - parser - -proc typeName*(v: MinValue): string {.extern:"min_exported_symbol_$1".}= - case v.kind: - of minInt: - return "int" - of minFloat: - return "float" - of minDictionary: - if v.isTypedDictionary: - return "dict:" & v.objType - else: - return "dict" - of minQuotation: - return "quot" - of minString: - return "string" - of minSymbol: - return "sym" - of minBool: - return "bool" - -# Constructors - -proc newVal*(s: string): MinValue {.extern:"min_exported_symbol_$1".}= - return MinValue(kind: minString, strVal: s) - -proc newVal*(s: cstring): MinValue {.extern:"min_exported_symbol_$1_2".}= - return MinValue(kind: minString, strVal: $s) - -proc newVal*(q: seq[MinValue]): MinValue {.extern:"min_exported_symbol_$1_3".}= - return MinValue(kind: minQuotation, qVal: q) - -proc newVal*(i: BiggestInt): MinValue {.extern:"min_exported_symbol_$1_4".}= - return MinValue(kind: minInt, intVal: i) - -proc newVal*(f: BiggestFloat): MinValue {.extern:"min_exported_symbol_$1_5".}= - return MinValue(kind: minFloat, floatVal: f) - -proc newVal*(s: bool): MinValue {.extern:"min_exported_symbol_$1_6".}= - return MinValue(kind: minBool, boolVal: s) - -proc newDict*(parentScope: ref MinScope): MinValue {.extern:"min_exported_symbol_$1".}= - return MinValue(kind: minDictionary, scope: newScopeRef(parentScope)) - -proc newSym*(s: string): MinValue {.extern:"min_exported_symbol_$1".}= - return MinValue(kind: minSymbol, symVal: s) - -# Get string value from string or quoted symbol - -proc getFloat*(v: MinValue): float {.extern:"min_exported_symbol_$1".}= - if v.isInt: - return v.intVal.float - elif v.isFloat: - return v.floatVal - else: - raiseInvalid("Value is not a number") - -proc getString*(v: MinValue): string {.extern:"min_exported_symbol_$1".}= - if v.isSymbol: - return v.symVal - elif v.isString: - return v.strVal - elif v.isQuotation: - if v.qVal.len != 1: - raiseInvalid("Quotation is not a quoted symbol") - let sym = v.qVal[0] - if sym.isSymbol: - return sym.symVal - else: - raiseInvalid("Quotation is not a quoted symbol") +import + parser + +proc typeName*(v: MinValue): string {.extern:"min_exported_symbol_$1".}= + case v.kind: + of minInt: + return "int" + of minFloat: + return "float" + of minDictionary: + if v.isTypedDictionary: + return "dict:" & v.objType + else: + return "dict" + of minQuotation: + return "quot" + of minString: + return "string" + of minSymbol: + return "sym" + of minNull: + return "null" + of minBool: + return "bool" + +# Constructors + +proc newNull*(): MinValue {.extern:"min_exported_symbol_$1".}= + return MinValue(kind: minNull) + +proc newVal*(s: string): MinValue {.extern:"min_exported_symbol_$1".}= + return MinValue(kind: minString, strVal: s) + +proc newVal*(s: cstring): MinValue {.extern:"min_exported_symbol_$1_2".}= + return MinValue(kind: minString, strVal: $s) + +proc newVal*(q: seq[MinValue]): MinValue {.extern:"min_exported_symbol_$1_3".}= + return MinValue(kind: minQuotation, qVal: q) + +proc newVal*(i: BiggestInt): MinValue {.extern:"min_exported_symbol_$1_4".}= + return MinValue(kind: minInt, intVal: i) + +proc newVal*(f: BiggestFloat): MinValue {.extern:"min_exported_symbol_$1_5".}= + return MinValue(kind: minFloat, floatVal: f) + +proc newVal*(s: bool): MinValue {.extern:"min_exported_symbol_$1_6".}= + return MinValue(kind: minBool, boolVal: s) + +proc newDict*(parentScope: ref MinScope): MinValue {.extern:"min_exported_symbol_$1".}= + return MinValue(kind: minDictionary, scope: newScopeRef(parentScope)) + +proc newSym*(s: string): MinValue {.extern:"min_exported_symbol_$1".}= + return MinValue(kind: minSymbol, symVal: s) + +# Get string value from string or quoted symbol + +proc getFloat*(v: MinValue): float {.extern:"min_exported_symbol_$1".}= + if v.isInt: + return v.intVal.float + elif v.isFloat: + return v.floatVal + else: + raiseInvalid("Value is not a number") + +proc getString*(v: MinValue): string {.extern:"min_exported_symbol_$1".}= + if v.isSymbol: + return v.symVal + elif v.isString: + return v.strVal + elif v.isQuotation: + if v.qVal.len != 1: + raiseInvalid("Quotation is not a quoted symbol") + let sym = v.qVal[0] + if sym.isSymbol: + return sym.symVal + else: + raiseInvalid("Quotation is not a quoted symbol")
M lib/min_lang.nimlib/min_lang.nim

@@ -835,7 +835,7 @@ let intcheck = v.isInt and v.intVal == 0

let floatcheck = v.isFloat and v.floatVal == 0 let boolcheck = v.isBool and v.boolVal == false let quotcheck = v.isQuotation and v.qVal.len == 0 - if strcheck or intcheck or floatcheck or boolcheck or quotcheck: + if v.isNull or strcheck or intcheck or floatcheck or boolcheck or quotcheck: i.push false.newVal else: i.push true.newVal

@@ -844,6 +844,8 @@ def.symbol("int") do (i: In):

let s = i.pop if s.isString: i.push s.getString.parseInt.newVal + elif s.isNull: + i.push 0.int.newVal elif s.isFloat: i.push s.floatVal.int.newVal elif s.isInt:

@@ -860,6 +862,8 @@ def.symbol("float") do (i: In):

let s = i.pop if s.isString: i.push s.getString.parseFloat.newVal + elif s.isNull: + i.push 0.int.newVal elif s.isInt: i.push s.intVal.float.newVal elif s.isFloat:
M lib/min_logic.nimlib/min_logic.nim

@@ -1,221 +1,227 @@

-import - math -import - ../core/parser, - ../core/value, - ../core/interpreter, - ../core/utils - -proc floatCompare(n1, n2: MinValue): bool = - let - a:float = if n1.kind != minFloat: n1.intVal.float else: n1.floatVal - b:float = if n2.kind != minFloat: n2.intVal.float else: n2.floatVal - if a.classify == fcNan and b.classify == fcNan: - return true - else: - const - FLOAT_MIN_NORMAL = 2e-1022 - FLOAT_MAX_VALUE = (2-2e-52)*2e1023 - epsilon = 0.00001 - let - absA = abs(a) - absB = abs(b) - diff = abs(a - b) - - if a == b: - return true - elif a == 0 or b == 0 or diff < FLOAT_MIN_NORMAL: - return diff < (epsilon * FLOAT_MIN_NORMAL) - else: - return diff / min((absA + absB), FLOAT_MAX_VALUE) < epsilon - -proc logic_module*(i: In)= - let def = i.define() - - def.symbol(">") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n2, n1 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal > n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float) - else: - i.push newVal(n1.strVal > n2.strVal) - - def.symbol(">=") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n2, n1 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal >= n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) - else: - i.push newVal(n1.strVal >= n2.strVal) - - def.symbol("<") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n1, n2 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal > n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float) - else: - i.push newVal(n1.strVal > n2.strVal) - - def.symbol("<=") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n1, n2 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal >= n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) - else: - i.push newVal(n1.strVal >= n2.strVal) - - def.symbol("==") do (i: In): - var n1, n2: MinValue - let vals = i.expect("a", "a") - n1 = vals[0] - n2 = vals[1] - if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: - i.push newVal(floatCompare(n1, n2)) - else: - i.push newVal(n1 == n2) - - def.symbol("!=") do (i: In): - var n1, n2: MinValue - let vals = i.expect("a", "a") - n1 = vals[0] - n2 = vals[1] - if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: - i.push newVal(not floatCompare(n1, n2)) - i.push newVal(not (n1 == n2)) - - def.symbol("not") do (i: In): - let vals = i.expect("bool") - let b = vals[0] - i.push newVal(not b.boolVal) - - def.symbol("and") do (i: In): - let vals = i.expect("bool", "bool") - let a = vals[0] - let b = vals[1] - i.push newVal(a.boolVal and b.boolVal) - - def.symbol("dequote-and") do (i: In): - let vals = i.expect("a", "a") - var a = vals[0] - var b = vals[1] - i.dequote(b) - let resB = i.pop - if (resB.isBool and resB.boolVal == false): - i.push(false.newVal) - else: - i.dequote(a) - let resA = i.pop - if not resA.isBool: - raiseInvalid("Result of first quotation is not a boolean value") - if not resB.isBool: - raiseInvalid("Result of second quotation is not a boolean value") - i.push newVal(resA.boolVal and resB.boolVal) - - def.symbol("or") do (i: In): - let vals = i.expect("bool", "bool") - let a = vals[0] - let b = vals[1] - i.push newVal(a.boolVal or b.boolVal) - - def.symbol("dequote-or") do (i: In): - let vals = i.expect("a", "a") - var a = vals[0] - var b = vals[1] - i.dequote(b) - let resB = i.pop - if (resB.isBool and resB.boolVal == true): - i.push(true.newVal) - else: - i.dequote(a) - let resA = i.pop - if not resA.isBool: - raiseInvalid("Result of first quotation is not a boolean value") - if not resB.isBool: - raiseInvalid("Result of second quotation is not a boolean value") - i.push newVal(resA.boolVal and resB.boolVal) - - def.symbol("xor") do (i: In): - let vals = i.expect("bool", "bool") - let a = vals[0] - let b = vals[1] - i.push newVal(a.boolVal xor b.boolVal) - - def.symbol("string?") do (i: In): - if i.pop.kind == minString: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("integer?") do (i: In): - if i.pop.kind == minInt: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("float?") do (i: In): - if i.pop.kind == minFloat: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("number?") do (i: In): - let a = i.pop - if a.kind == minFloat or a.kind == minInt: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("boolean?") do (i: In): - if i.pop.kind == minBool: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("quotation?") do (i: In): - if i.pop.kind == minQuotation: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("dictionary?") do (i: In): - if i.pop.isDictionary: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("type?") do (i: In): - let vals = i.expect("'sym", "a") - if vals[1].isTypedDictionary(vals[0].getString): - i.push true.newVal - else: - i.push (vals[1].typename == vals[0].getString).newVal - - def.finalize("logic") +import + math +import + ../core/parser, + ../core/value, + ../core/interpreter, + ../core/utils + +proc floatCompare(n1, n2: MinValue): bool = + let + a:float = if n1.kind != minFloat: n1.intVal.float else: n1.floatVal + b:float = if n2.kind != minFloat: n2.intVal.float else: n2.floatVal + if a.classify == fcNan and b.classify == fcNan: + return true + else: + const + FLOAT_MIN_NORMAL = 2e-1022 + FLOAT_MAX_VALUE = (2-2e-52)*2e1023 + epsilon = 0.00001 + let + absA = abs(a) + absB = abs(b) + diff = abs(a - b) + + if a == b: + return true + elif a == 0 or b == 0 or diff < FLOAT_MIN_NORMAL: + return diff < (epsilon * FLOAT_MIN_NORMAL) + else: + return diff / min((absA + absB), FLOAT_MAX_VALUE) < epsilon + +proc logic_module*(i: In)= + let def = i.define() + + def.symbol(">") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n2, n1 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal > n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float) + else: + i.push newVal(n1.strVal > n2.strVal) + + def.symbol(">=") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n2, n1 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal >= n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) + else: + i.push newVal(n1.strVal >= n2.strVal) + + def.symbol("<") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n1, n2 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal > n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float) + else: + i.push newVal(n1.strVal > n2.strVal) + + def.symbol("<=") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n1, n2 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal >= n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) + else: + i.push newVal(n1.strVal >= n2.strVal) + + def.symbol("==") do (i: In): + var n1, n2: MinValue + let vals = i.expect("a", "a") + n1 = vals[0] + n2 = vals[1] + if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: + i.push newVal(floatCompare(n1, n2)) + else: + i.push newVal(n1 == n2) + + def.symbol("!=") do (i: In): + var n1, n2: MinValue + let vals = i.expect("a", "a") + n1 = vals[0] + n2 = vals[1] + if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: + i.push newVal(not floatCompare(n1, n2)) + i.push newVal(not (n1 == n2)) + + def.symbol("not") do (i: In): + let vals = i.expect("bool") + let b = vals[0] + i.push newVal(not b.boolVal) + + def.symbol("and") do (i: In): + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] + i.push newVal(a.boolVal and b.boolVal) + + def.symbol("dequote-and") do (i: In): + let vals = i.expect("a", "a") + var a = vals[0] + var b = vals[1] + i.dequote(b) + let resB = i.pop + if (resB.isBool and resB.boolVal == false): + i.push(false.newVal) + else: + i.dequote(a) + let resA = i.pop + if not resA.isBool: + raiseInvalid("Result of first quotation is not a boolean value") + if not resB.isBool: + raiseInvalid("Result of second quotation is not a boolean value") + i.push newVal(resA.boolVal and resB.boolVal) + + def.symbol("or") do (i: In): + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] + i.push newVal(a.boolVal or b.boolVal) + + def.symbol("dequote-or") do (i: In): + let vals = i.expect("a", "a") + var a = vals[0] + var b = vals[1] + i.dequote(b) + let resB = i.pop + if (resB.isBool and resB.boolVal == true): + i.push(true.newVal) + else: + i.dequote(a) + let resA = i.pop + if not resA.isBool: + raiseInvalid("Result of first quotation is not a boolean value") + if not resB.isBool: + raiseInvalid("Result of second quotation is not a boolean value") + i.push newVal(resA.boolVal and resB.boolVal) + + def.symbol("xor") do (i: In): + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] + i.push newVal(a.boolVal xor b.boolVal) + + def.symbol("string?") do (i: In): + if i.pop.kind == minString: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("integer?") do (i: In): + if i.pop.kind == minInt: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("float?") do (i: In): + if i.pop.kind == minFloat: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("null?") do (i: In): + if i.pop.kind == minNull: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("number?") do (i: In): + let a = i.pop + if a.kind == minFloat or a.kind == minInt: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("boolean?") do (i: In): + if i.pop.kind == minBool: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("quotation?") do (i: In): + if i.pop.kind == minQuotation: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("dictionary?") do (i: In): + if i.pop.isDictionary: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("type?") do (i: In): + let vals = i.expect("'sym", "a") + if vals[1].isTypedDictionary(vals[0].getString): + i.push true.newVal + else: + i.push (vals[1].typename == vals[0].getString).newVal + + def.finalize("logic")
M next-release.mdnext-release.md

@@ -6,3 +6,4 @@ * 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.
M site/contents/_defs_.mdsite/contents/_defs_.md

@@ -46,7 +46,8 @@ {{sl1 => [&apos;sym<sub>1</sub>](class:kwd)}}

{{sl2 => [&apos;sym<sub>2</sub>](class:kwd)}} {{f => [false](class:kwd)}} {{t => [true](class:kwd)}} -{{null => &#x2205;}} +{{null => [null](class:kwd)}} +{{none => &#x2205;}} {{sock => [dict:socket](class:kwd)}} {{url => [url](class:kwd)}} {{req => [request](class:kwd)}}
M site/contents/learn-data-types.mdsite/contents/learn-data-types.md

@@ -7,6 +7,8 @@

The type system of min is very simple -- only the following data types are available: +null +: null value. boolean : **true** or **false**. integer
M site/contents/reference-http.mdsite/contents/reference-http.md

@@ -4,7 +4,7 @@ title: "http Module"

----- {@ _defs_.md || 0 @} -{#op||download||{{s1}} {{s2}}||{{null}}|| +{#op||download||{{s1}} {{s2}}||{{none}}|| Downloads the contents of URL {{s1}} to the local file {{s2}}. #} {#op||get-content||{{s1}}||{{s2}}||

@@ -24,7 +24,7 @@ > > "http://httpbin.org/ip" %url

> > request #} -{#op||start-server||{{d}}||{{null}}|| +{#op||start-server||{{d}}||{{none}}|| > Starts an HTTP server based on the configuration provided in {{d}}. > > {{d}} is a dictionary containing the following keys:

@@ -80,5 +80,5 @@ > > "Press Ctrl+C to stop." puts!

> > start-server #} -{#op||stop-server||{{null}}||{{null}}|| -Stops the currently-running HTTP server. This operator should be used within an HTTP server handler quotation.#} +{#op||stop-server||{{none}}||{{none}}|| +Stops the currently-running HTTP server. This operator should be used within an HTTP server handler quotation.#}
M site/contents/reference-io.mdsite/contents/reference-io.md

@@ -12,7 +12,7 @@ > Prints {{s2}}, then prints all {{s1}} included in the quotation prepended with a number, and waits from valid input from the user.

> > If the user enters a number that matches one of the choices, then the corresponding quotation {{q1}} is executed, otherwise the choice menu is displayed again until a valid choice is made. #} -{#op||clear||{{null}}||{{null}}|| +{#op||clear||{{none}}||{{none}}|| Clears the screen.#} {#op||column-print||{{q}} {{i}}||{{any}}||

@@ -31,7 +31,7 @@

{#op||error||{{any}}||{{any}}|| Prints {{any}} and a new line to STDERR, if logging level is set to [error](class:kwd) or lower.#} -{#op||fappend||{{s1}} {{s2}}||{{null}}|| +{#op||fappend||{{s1}} {{s2}}||{{none}}|| Appends {{s1}} to the end of file {{s2}}. #} {#op||fatal||{{any}}||{{any}}||

@@ -40,16 +40,16 @@

{#op||fread||{{s}}||{{s}}|| Reads the file {{s}} and puts its contents on the top of the stack as a string.#} -{#op||fwrite||{{s1}} {{s2}}||{{null}}|| +{#op||fwrite||{{s1}} {{s2}}||{{none}}|| Writes {{s1}} to the file {{s2}}, erasing all its contents first. #} -{#op||getchr||{{null}}||{{i}}|| +{#op||getchr||{{none}}||{{i}}|| Reads single character from STDIN without waiting for ENTER key and places its ASCII code on top of the stack.#} {#op||info||{{any}}||{{any}}|| Prints {{any}} and a new line to STDOUT, if logging level is set to [info](class:kwd) or lower.#} -{#op||mapkey||{{q}} {{sl}}||{{null}}|| +{#op||mapkey||{{q}} {{sl}}||{{none}}|| > Maps the named key/key combination {{sl}} to the quotation {{q}}, so that {{q}} is executed when key {{sl}} is pressed. > > > %note%

@@ -67,19 +67,19 @@ > > (clear) 'ctrl+l keymap

> > > > causes the `CTRL+L` key to clear the screen. #} -{#op||newline||{{null}}||{{null}}|| +{#op||newline||{{none}}||{{none}}|| Prints a new line to STDOUT.#} {#op||notice||{{any}}||{{any}}|| Prints {{any}} and a new line to STDOUT, if logging level is set to [notice](class:kwd) (default) or lower.#} -{#op||password||{{null}}||{{s}}|| +{#op||password||{{none}}||{{s}}|| Reads a line from STDIN displaying \* for each typed character, and places it on top of the stack as a string.#} {#op||print||{{any}}||{{any}}|| Prints {{any}} to STDOUT.#} -{#op||print!||{{any}}||{{null}}|| +{#op||print!||{{any}}||{{none}}|| Prints {{any}} to STDOUT and removes {{any}} from the stack.#} {#op||putchr||{{s}}||{{any}}||

@@ -88,7 +88,7 @@

{#op||type||{{any}}||{{s}}|| Puts the data type of {{any}} on the stack. In cased of typed dictionaries, the type name is prefixed by `dict:`, e.g. `dict:module`, `dict:socket`, etc.#} -{#op||unmapkey||{{sl}}||{{null}}|| +{#op||unmapkey||{{sl}}||{{none}}|| > Unmaps a previously-mapped key or key-combination {{sl}}, restoring the default mapping if available. > > > %note%

@@ -100,4 +100,3 @@ #}

{#op||warning||{{any}}||{{any}}|| Prints {{any}} and a new line to STDERR, if logging level is set to [warning](class:kwd) or lower.#} -
M site/contents/reference-lang.mdsite/contents/reference-lang.md

@@ -54,16 +54,17 @@ >

> * If a quotation {{q}} is passed, it returns a new quotation obtained by evaluating each element of {{q}} in a separate stack. > * If a dictionary {{d}} (with values and keys) is passed, it returns a new dictionary obtained by evaluating each value in the dict that is a symbol in a separate stack (values that aren't symbols stay as they are).#} -{#op||args||{{null}}||{{q}}|| +{#op||args||{{none}}||{{q}}|| Returns a list of all arguments passed to the current program.#} -{#op||bind||{{any}} {{sl}}||{{null}}|| +{#op||bind||{{any}} {{sl}}||{{none}}|| Binds the specified value (auto-quoted) to an existing symbol {{sl}}.#} {#op||bool||{{any}}||{{b}}|| > Converts {{any}} to a boolean value based on the following rules: > > * If {{any}} is a boolean value, no conversion is performed. +> * If {{any}} is {{null}}, it is converted to {{f}}. > * If {{any}} is a numeric value, zero is converted to {{f}}, otherwise it is converted to {{t}}. > * If {{any}} is a quotation or a dictionary, the empty quotation or dictionary is converted to {{f}}, otherwise it is converted to {{t}}. > * If {{any}} is a string, the empty string, and `"false"` are converted to {{f}}, otherwise it is converted to {{t}}.#}

@@ -90,13 +91,13 @@ > > ((< 3) ("Smaller than 3" put!))

> > ((true) ("Exactly 3" put!)) > > ) case #} -{#op||compiled?||{{null}}||{{b}}|| +{#op||compiled?||{{none}}||{{b}}|| Returns {{t}} if the current program has been compiled.#} -{#op||define||{{any}} {{sl}}||{{null}}|| +{#op||define||{{any}} {{sl}}||{{none}}|| Defines a new symbol {{sl}}, containing the specified value (auto-quoted if not already a quotation).#} -{#op||define-sigil||{{any}} {{sl}}||{{null}}|| +{#op||define-sigil||{{any}} {{sl}}||{{none}}|| Defines a new sigil {{sl}}, containing the specified value (auto-quoted if not already a quotation).#} {#op||defined?||{{sl}}||{{b}}||

@@ -105,10 +106,10 @@

{#op||defined-sigil?||{{sl}}||{{b}}|| Returns {{t}} if the symbol {{sl}} is defined, {{f}} otherwise.#} -{#op||delete||{{sl}}||{{null}}|| +{#op||delete||{{sl}}||{{none}}|| Deletes the specified symbol {{sl}}.#} -{#op||delete-sigil||{{sl}}||{{null}}|| +{#op||delete-sigil||{{sl}}||{{none}}|| Deletes the specified user-defined sigil {{sl}}.#} {#op||dequote||{{q}}||{{a0p}}||

@@ -119,7 +120,7 @@

{#op||eval||{{s}}||{{a0p}}|| Parses and interprets {{s}}. #} -{#op||exit||{{i}}||{{null}}|| +{#op||exit||{{i}}||{{none}}|| Exits the program or shell with {{i}} as return code. #} {#op||expect||{{q1}}||{{q2}}||

@@ -142,7 +143,7 @@ > > the following program evaluates to `true`:

> > > > `(int string num) expect (3.4 "test" 1) ==`#} -{#op||expect-empty-stack||{{null}}||{{null}}|| +{#op||expect-empty-stack||{{none}}||{{none}}|| Raises an error if the stack is not empty.#}

@@ -151,7 +152,8 @@ > Converts {{any}} to an integer value based on the following rules:

> > * If {{any}} is {{t}}, it is converted to `1.0`. > * If {{any}} is {{f}}, it is converted to `0.0`. -> * If {{any}} is a integer, it is converted to float value. +> * If {{any}} is {{null}}, it is converted to `0.0` +>. * If {{any}} is a integer, it is converted to float value. > * If {{any}} is a float, no conversion is performed. > * If {{any}} is a string, it is parsed as a float value.#}

@@ -179,13 +181,13 @@ > > Note

> > > > At present, only YAML objects containing string values are supported.#} -{#op||gets||{{null}}||{{s}}|| +{#op||gets||{{none}}||{{s}}|| Reads a line from STDIN and places it on top of the stack as a string.#} {#op||if||{{q1}} {{q2}} {{q3}}||{{a0p}}|| If {{q1}} evaluates to {{t}} then evaluates {{q2}}, otherwise evaluates {{q3}}.#} -{#op||import||{{sl}}||{{null}}|| +{#op||import||{{sl}}||{{none}}|| Imports the a previously-loaded module {{sl}}, defining all its symbols in the current scope. #} {#op||infix-dequote||{{q}}||{{any}}||

@@ -210,6 +212,7 @@ > Converts {{any}} to an integer value based on the following rules:

> > * If {{any}} is {{t}}, it is converted to `1`. > * If {{any}} is {{f}}, it is converted to `0`. +> * If {{any}} is {{null}}, it is converted to `0`. > * If {{any}} is an integer, no conversion is performed. > * If {{any}} is a float, it is converted to an integer value by truncating its decimal part. > * If {{any}} is a string, it is parsed as an integer value.#}

@@ -241,7 +244,7 @@ > >

> > 5 (dup 0 ==) 'succ (dup pred) '* linrec #} -{#op||lite?||{{null}}||{{b}}|| +{#op||lite?||{{none}}||{{b}}|| Returns {{t}} if min was built in _lite_ mode. #} {#op||load||{{sl}}||{{a0p}}||

@@ -250,7 +253,7 @@

{#op||load-symbol||{{sl}}||{{a0p}}|| Loads the contents of symbol {{sl}} from the [.min\_symbols](class:file) file. #} -{#op||loglevel||{{sl}}||{{null}}|| +{#op||loglevel||{{sl}}||{{none}}|| > Sets the current logging level to {{sl}}. {{sl}} must be one of the following strings or quoted symbols: > > * debug

@@ -265,13 +268,13 @@ > > Note

> > > > The default logging level is _notice_.#} -{#op||loglevel?||{{null}}||{{s}}|| +{#op||loglevel?||{{none}}||{{s}}|| Returns the current log level (debug, info, notive, warn, error or fatal). #} -{#op||module||{{d}} {{sl}}||{{null}}|| +{#op||module||{{d}} {{sl}}||{{none}}|| Creates a new module {{sl}} based on dictionary {{d}}. #} -{#op||opts||{{null}}||{{d}}|| +{#op||opts||{{none}}||{{d}}|| Returns a dictionary of all options passed to the current program, with their respective values.#} {#op||parse||{{s}}||{{q}}||

@@ -288,14 +291,14 @@ > >

> > (* 8 4) prefix-dequote #} -{#op||prompt||{{null}}||{{s}}|| +{#op||prompt||{{none}}||{{s}}|| > This symbol is used to configure the prompt of the min shell. By default, it is set to the following quotation: > > ("[$1]$$ " (.) => %) > > Unlike other predefined symbols, this symbol is _unsealed_, which means it can be modified.#} -{#op||publish||{{sl}} {{d}}||{{null}}|| +{#op||publish||{{sl}} {{d}}||{{none}}|| > Publishes symbol {{sl}} to the scope of {{d}}. > > > %sidebar%

@@ -307,34 +310,34 @@

{#op||puts||{{any}}||{{any}}|| Prints {{any}} and a new line to STDOUT.#} -{#op||puts!||{{any}}||{{null}}|| +{#op||puts!||{{any}}||{{none}}|| Prints {{any}} and a new line to STDOUT, removing {{any}} from the stack.#} -{#op||quit||{{null}}||{{null}}|| +{#op||quit||{{none}}||{{none}}|| Exits the program or shell with 0 as return code. #} {#op||quote||{{any}}||({{any}})|| Wraps {{any}} in a quotation. #} -{#op||quote-bind||{{any}} {{sl}}||{{null}}|| +{#op||quote-bind||{{any}} {{sl}}||{{none}}|| Quotes {{any}} and binds the quotation to the existing symbol {{sl}}. #} -{#op||quote-define||{{any}} {{sl}}||{{null}}|| +{#op||quote-define||{{any}} {{sl}}||{{none}}|| Quotes {{any}} and assigns the quotation to the symbol {{sl}}, creating it if not already defined. #} -{#op||raise||{{e}}||{{null}}|| +{#op||raise||{{e}}||{{none}}|| Raises the error specified via the dictionary {{e}}.#} {#op||read||{{sl}}||{{q}}|| Reads and parses the specified {{m}} file {{sl}} and returns a quoted program {{q}}. #} -{#op||remove-symbol||{{sl}}||{{null}}|| +{#op||remove-symbol||{{sl}}||{{none}}|| Removes the symbol {{sl}} from the [.min\_symbols](class:file) file. #} {#op||require||{{sl}}||{{d}}|| Parses and interprets (in a separater interpreter) the specified {{m}} file {{sl}}, adding [.min](class:ext) if not specified, and returns a module dictionary {{d}} containing all the symbols defined in {{sl}}. #} -{#op||ROOT||{{null}}||{{d}}|| +{#op||ROOT||{{none}}||{{d}}|| Returns a module holding a reference to the [ROOT](class:kwd) scope. > > %tip%

@@ -343,10 +346,10 @@ > >

> > This symbol is very useful in conjunction with the **with** operator. #} -{#op||save-symbol||{{sl}}||{{null}}|| +{#op||save-symbol||{{sl}}||{{none}}|| Saves the contents of symbol {{sl}} to the [.min\_symbols](class:file) file. #} -{#op||scope||{{null}}||{{d}}|| +{#op||scope||{{none}}||{{d}}|| > Returns a dictionary {{d}} holding a reference to the current scope. > > This can be useful to save a reference to a given execution scope to access later on.

@@ -359,7 +362,7 @@ > >

> > {} :myscope (2 :due scope @myscope) -> #} -{#op||saved-symbols||{{null}}||({{s0p}})|| +{#op||saved-symbols||{{none}}||({{s0p}})|| Returns a quotation containing all symbols saved in the [.min\_symbols](class:file) file. #} {#op||scope-sigils||{{d}}||({{s0p}})||

@@ -368,16 +371,16 @@

{#op||scope-symbols||{{d}}||({{s0p}})|| Returns a list of all symbols defined in dictionary {{d}}.#} -{#op||seal||{{sl}}||{{null}}|| +{#op||seal||{{sl}}||{{none}}|| Seals symbol {{sl}}, so that it cannot be re-assigned. #} -{#op||seal-sigil||{{sl}}||{{null}}|| +{#op||seal-sigil||{{sl}}||{{none}}|| Seals the user-defined sigil {{sl}}, so that it cannot be re-defined. #} {#op||set-type||{{d}} {{sl}}||{{d}}|| Sets the type for dictionary {{d}} to {{sl}}.#} -{#op||sigils||{{null}}||({{s0p}})|| +{#op||sigils||{{none}}||({{s0p}})|| Returns a list of all sigils defined in the [ROOT](class:kwd) scope.#} {#op||source||{{sl}}||{{q}}||

@@ -386,7 +389,7 @@

{#op||string||{{any}}||{{s}}|| Converts {{any}} to its string representation.#} -{#op||symbols||{{null}}||({{s0p}})|| +{#op||symbols||{{none}}||({{s0p}})|| Returns a list of all symbols defined in the [ROOT](class:kwd) scope.#} {#op||tap||{{any}} {{q}}||{{any}}||

@@ -469,13 +472,13 @@

{#op||unless||{{q1}} {{q2}}||{{a0p}}|| If {{1}} evaluates to {{f}} then evaluates {{2}}.#} -{#op||unseal||{{sl}}||{{null}}|| +{#op||unseal||{{sl}}||{{none}}|| Unseals the user-defined symbol {{sl}}, so that it can be re-assigned. #} -{#op||unseal-sigil||{{sl}}||{{null}}|| +{#op||unseal-sigil||{{sl}}||{{none}}|| Unseals sigil {{sl}}, so that it can be re-defined (system sigils cannot be unsealed). #} -{#op||version||{{null}}||{{s}}|| +{#op||version||{{none}}||{{s}}|| Returns the current min version number. #} {#op||when||{{q1}} {{q2}}||{{a0p}}||
M site/contents/reference-logic.mdsite/contents/reference-logic.md

@@ -102,6 +102,9 @@

{#op||not||{{b1}}||{{b2}}|| Negates {{b1}}.#} +{#op||null?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is {{null}}, {{f}} otherwise. #} + {#op||number?||{{any}}||{{b}}|| Returns {{t}} if {{any}} is a number, {{f}} otherwise. #}
M site/contents/reference-math.mdsite/contents/reference-math.md

@@ -25,7 +25,7 @@

{#op||d2r||{{n1}}||{{n2}}|| Converts {{n1}} from degrees to radians. #} -{#op||e||{{null}}||{{n}}|| +{#op||e||{{none}}||{{n}}|| Returns the value of the _e_ constant (Euler's number). #} {#op||floor||{{n}}||{{i}}||

@@ -40,7 +40,7 @@

{#op||log2||{{n1}}||{{n2}}|| Calculates the binary logarithm of {{n1}}. #} -{#op||pi||{{null}}||{{n}}|| +{#op||pi||{{none}}||{{n}}|| Returns the value of the &pi; constant. #} {#op||pow||{{n1}} {{n2}}||{{n3}}||

@@ -67,9 +67,8 @@

{#op||tanh||{{n1}}||{{n2}}|| Calculates the hyperbolic tangent of {{n1}} (in radians). #} -{#op||tau||{{null}}||{{n}}|| +{#op||tau||{{none}}||{{n}}|| Returns the value of the &tau; constant (2&pi;). #} {#op||trunc||{{n1}}||{{n2}}|| Truncates {{n}} to the decimal point. #} -
M site/contents/reference-net.mdsite/contents/reference-net.md

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

{#op||accept||{{sock1}} {{sock2}}||{{sock1}}|| Makes {{sock2}} (server) accept a connection from {{sock1}} (client). Returns the client socket {{sock1}} from which it will be possible to receive data from. #} -{#op||close||{{sock}}||{{null}}|| +{#op||close||{{sock}}||{{none}}|| Closes a previously-opened socket. #} {#op||connect||{{sock}} {{s}} {{i}}||{{sock}}||

@@ -85,7 +85,7 @@ > > cli recv-line puts @line

> > ) while #} -{#op||send||{{sock}} {{s}}||{{null}}|| +{#op||send||{{sock}} {{s}}||{{none}}|| Sends {{s}} to the connected socket {{sock}}. #} {#op||socket||{{d}}||{{sock}}||

@@ -116,4 +116,3 @@ > * **ipv6**: Internet Protocol version 6 {{no-win}}.

> * **raw**: Raw IP Packets protocol {{no-win}}. > * **icmp**: Internet Control Message Protocol {{no-win}}. #} -
M site/contents/reference-num.mdsite/contents/reference-num.md

@@ -10,7 +10,7 @@

{#op||-||{{n1}} {{n2}}||{{n3}}|| Subtracts {{n2}} from {{n1}}. #} -{#op||-inf||{{null}}||{{n}}|| +{#op||-inf||{{none}}||{{n}}|| Returns negative infinity. #} {#op||\*||{{n1}} {{n2}}||{{n3}}||

@@ -25,13 +25,13 @@

{#op||div||{{i1}} {{i2}}||{{i3}}|| Divides {{i1}} by {{i2}} (integer division). #} -{#op||inf||{{null}}||{{n}}|| +{#op||inf||{{none}}||{{n}}|| Returns infinity. #} {#op||mod||{{i1}} {{i2}}||{{i3}}|| Returns the integer module of {{i1}} divided by {{i2}}. #} -{#op||nan||{{null}}||nan|| +{#op||nan||{{none}}||nan|| Returns **NaN** (not a number). #} {#op||odd?||{{i}}||{{b}}||

@@ -48,11 +48,11 @@ > > Note

> > > > You must call `randomize` to initialize the random number generator, otherwise the same sequence of numbers will be returned.#} -{#op||randomize||{{null}}||{{null}|| +{#op||randomize||{{none}}||{{null}|| Initializes the random number generator using a seed based on the current timestamp. #} {#op||succ||{{i1}}||{{i2}}|| Returns the successor of {{i1}}.#} {#op||sum||{{q}}||{{i}}|| -Returns the sum of all items of {{q}}. {{q}} is a quotation of integers. #} +Returns the sum of all items of {{q}}. {{q}} is a quotation of integers. #}
M site/contents/reference-stack.mdsite/contents/reference-stack.md

@@ -4,7 +4,7 @@ title: "stack Module"

----- {@ _defs_.md || 0 @} -{#op||clear-stack||{{any}}||{{null}}|| +{#op||clear-stack||{{any}}||{{none}}|| Empties the stack.#} {#op||cleave||{{a1}} ({{q}}{{0p}})||{{a0p}}||

@@ -25,10 +25,10 @@

{#op||dup||{{a1}}||{{a1}} {{a1}}|| Duplicates the first element on the stack.#} -{#op||get-stack||{{null}}||({{a0p}})|| +{#op||get-stack||{{none}}||({{a0p}})|| Puts a quotation containing the contents of the stack on the stack.#} -{#op||id||{{null}}||{{null}}|| +{#op||id||{{none}}||{{none}}|| Does nothing.#} {#op||keep||{{a1}} {{q}}||{{a0p}} {{a1}}||

@@ -49,7 +49,7 @@

{#op||pick||{{a1}} {{a2}} {{a3}}||{{a1}} {{a2}} {{a3}} {{a1}}|| Pushes a copy of the third element on top of the stack.#} -{#op||pop||{{any}}||{{null}}|| +{#op||pop||{{any}}||{{none}}|| Removes the first element from the stack.#} {#op||rolldown||{{a1}} {{a2}} {{a3}}||{{a2}} {{a3}} {{a1}}||

@@ -77,4 +77,4 @@ {#op||swap||{{a1}} {{a2}}||{{a2}} {{a1}}||

Swaps the first two elements on the stack. #} {#op||swons||({{a0p}}) {{a1}}||({{a1}} {{a0p}})|| -Prepends {{a1}} to the quotation that follows it.#} +Prepends {{a1}} to the quotation that follows it.#}
M site/contents/reference-sys.mdsite/contents/reference-sys.md

@@ -18,13 +18,13 @@ {#sig||&||run#}

{#alias||&||run#} -{#op||.||{{null}}||{{s}}|| +{#op||.||{{none}}||{{s}}|| Returns the full path to the current directory. #} -{#op||..||{{null}}||{{s}}|| +{#op||..||{{none}}||{{s}}|| Returns the full path to the parent directory. #} -{#op||chmod||{{sl}} {{i}}||{{null}}|| +{#op||chmod||{{sl}} {{i}}||{{none}}|| > Sets the permissions of file or directory {{sl}} to {{i}}. {{i}} is a three-digit representation of user, group and other permissions. See the [Unix Permissions Calculator](http://permissions-calculator.org/) for examples and conversions. > > > %sidebar%

@@ -34,13 +34,13 @@ > > The following program makes the file **/tmp/test.txt** readable, writable and executable by its owner, and readable and executable by users of the same group and all other users:

> > > > `/tmp/test.txt 755 chmod`#} -{#op||cd||{{sl}}||{{null}}|| +{#op||cd||{{sl}}||{{none}}|| Change the current directory to {{{sl}}. #} -{#op||cp||{{sl1}} {{sl2}}||{{null}}|| +{#op||cp||{{sl1}} {{sl2}}||{{none}}|| Copies the file or directory {{sl1}} to {{sl2}}. #} -{#op||cpu||{{null}}||{{s}}|| +{#op||cpu||{{none}}||{{s}}|| Returns the host CPU. It can be one of the following strings i386, alpha, powerpc, powerpc64, powerpc64el, sparc, amd64, mips, mipsel, arm, arm64. #} {#op||env?||{{sl}}||{{b}}||

@@ -64,7 +64,7 @@

{#op||get-env||{{sl}}||{{s}}|| Returns environment variable {{sl}}. #} -{#op||hardlink||{{sl1}} {{sl2}}||{{null}}|| +{#op||hardlink||{{sl1}} {{sl2}}||{{none}}|| Creates hardlink {{sl2}} for file or directory {{sl1}}. #} {#op||ls||{{sl}}||{{q}}||

@@ -73,31 +73,31 @@

{#op||ls-r||{{sl}}||{{q}}|| Returns a quotation {{q}} containing all children (files and directories) of the directory {{sl}}, recursively. #} -{#op||mkdir||{{sl}}||{{null}}|| +{#op||mkdir||{{sl}}||{{none}}|| Creates the specified directory {{sl}}. #} -{#op||mv||{{sl1}} {{sl2}}||{{null}}|| +{#op||mv||{{sl1}} {{sl2}}||{{none}}|| Moves the file or directory {{sl1}} to {{sl2}}. #} -{#op||os||{{null}}||{{s}}|| +{#op||os||{{none}}||{{s}}|| Returns the host operating system. It can be one of the following strings: windows, macosx, linux, netbsd, freebsd, openbsd, solaris, aix, standalone. #} {#op||put-env||{{sl1}} {{sl2}}||{{s}}|| Sets environment variable {{sl2}} to {{sl1}}. #} -{#op||rm||{{sl}}||{{null}}|| +{#op||rm||{{sl}}||{{none}}|| Deletes the specified file {{sl}}. #} -{#op||rmdir||{{sl}}||{{null}}|| +{#op||rmdir||{{sl}}||{{none}}|| Deletes the specified directory {{sl}} and all its subdirectories recursively. #} {#op||run||{{sl}}||{{d}}|| Executes the external command {{sl}} in the current directory without displaying its output. Returns a dictionary containing the command output and return code (in keys **output** and **code** respectively). #} -{#op||sleep||{{i}}||{{null}}|| +{#op||sleep||{{i}}||{{none}}|| Halts program execution for {{i}} milliseconds.#} -{#op||symlink||{{sl1}} {{sl2}}||{{null}}|| +{#op||symlink||{{sl1}} {{sl2}}||{{none}}|| Creates symlink {{sl2}} for file or directory {{sl1}}. #} {#op||symlink?||{{sl}}||{{b}}||

@@ -106,14 +106,14 @@

{#op||system||{{sl}}||{{i}}|| Executes the external command {{sl}} in the current directory and pushes its return code on the stack. #} -{#op||system!||{{sl}}||{{null}}|| +{#op||system!||{{sl}}||{{none}}|| Executes the external command {{sl}} in the current directory without pushing its return code on the stack. #} -{#op||unzip||{{sl1}} {{sl2}}||{{null}}|| +{#op||unzip||{{sl1}} {{sl2}}||{{none}}|| Decompresses zip file {{sl1}} to directory {{sl2}} (created if not present).#} {#op||which||{{sl}}||{{s}}|| Returns the full path to the directory containing executable {{sl}}, or an empty string if the executable is not found in **$PATH**. #} -{#op||zip||{{sl}} {{q}}||{{null}}|| -Compresses files included in quotation {{q}} into zip file {{sl}}.#} +{#op||zip||{{sl}} {{q}}||{{none}}|| +Compresses files included in quotation {{q}} into zip file {{sl}}.#}
M site/contents/reference-time.mdsite/contents/reference-time.md

@@ -4,10 +4,10 @@ title: "time Module"

----- {@ _defs_.md || 0 @} -{#op||now||{{null}}||{{flt}}|| +{#op||now||{{none}}||{{flt}}|| Returns the current time as Unix timestamp with microseconds. #} -{#op||timestamp||{{null}}||{{i}}|| +{#op||timestamp||{{none}}||{{i}}|| Returns the current time as Unix timestamp. #} {#op||timeinfo||{{i}}||{{tinfo}}||

@@ -26,4 +26,4 @@ >

> > %tip% > > Tip > > -> > For information on special characters in the format string, see the [format](https://nim-lang.org/docs/times.html#format,TimeInfo,string) nim method. #} +> > For information on special characters in the format string, see the [format](https://nim-lang.org/docs/times.html#format,TimeInfo,string) nim method. #}
M site/contents/reference.mdsite/contents/reference.md

@@ -46,8 +46,10 @@ The following notation is used in the signature of all min operators:

### Types and Values -{{null}} +{{none}} : No value. +{{null}} +: null value {{any}} : A value of any type. {{b}}