Implemented expect proc to use instead of most validators.
@@ -1,5 +1,6 @@
import strutils, + sequtils, critbits, json, terminal@@ -9,6 +10,11 @@ parser,
value, scope, interpreter + +proc reverse[T](xs: openarray[T]): seq[T] = + result = newSeq[T](xs.len) + for i, x in xs: + result[^i-1] = x # Library methods@@ -151,41 +157,50 @@ return res.newVal(i.scope)
# Validators -proc reqStackSize*(i: var MinInterpreter, n: int) = - if i.stack.len < n: - raiseEmptyStack() - -proc reqBool*(i: var MinInterpreter, a: var MinValue) = - a = i.pop - if not a.isBool: - raiseInvalid("A bool value is required on the stack") - -proc reqTwoBools*(i: var MinInterpreter, a, b: var MinValue) = - a = i.pop - b = i.pop - if not a.isBool or not b.isBool: - raiseInvalid("Two bool values are required on the stack") - -proc reqInt*(i: var MinInterpreter, a: var MinValue) = - a = i.pop - if not a.isInt: - raiseInvalid("An integer is required on the stack") - -proc reqNumber*(i: var MinInterpreter, a: var MinValue) = - a = i.pop - if not a.isNumber: - raiseInvalid("A number is required on the stack") - -proc reqTwoInts*(i: var MinInterpreter, a, b: var MinValue) = - a = i.pop - b = i.pop - if not a.isInt or not b.isInt: - raiseInvalid("Two integers are required on the stack") - -proc reqQuotation*(i: var MinInterpreter, a: var MinValue) = - a = i.pop - if not a.isQuotation: - raiseInvalid("A quotation is required on the stack") +proc expect*(i: var MinInterpreter, elements: varargs[string]): seq[MinValue] = + let stack = elements.reverse.join(" ") + var valid = newSeq[string](0) + result = newSeq[MinValue](0) + let message = proc(invalid: string): string = + result = "Incorrect values found on the stack:\n" + result &= "- expected: {" & stack & "}\n" + result &= "- got: {" & invalid & " " & valid.reverse.join(" ") & "}" + for element in elements: + let value = i.pop + result.add value + case element: + of "bool": + if not value.isBool: + raiseInvalid(message(value.typeName)) + of "int": + if not value.isInt: + raiseInvalid(message(value.typeName)) + of "num": + if not value.isNumber: + raiseInvalid(message(value.typeName)) + of "quot": + if not value.isQuotation: + raiseInvalid(message(value.typeName)) + of "dict": + if not value.isDictionary: + raiseInvalid(message(value.typeName)) + of "'sym": + if not value.isStringLike: + raiseInvalid(message(value.typeName)) + of "sym": + if not value.isSymbol: + raiseInvalid(message(value.typeName)) + of "float": + if not value.isFloat: + raiseInvalid(message(value.typeName)) + of "string": + if not value.isString: + raiseInvalid(message(value.typeName)) + of "a": + discard # any type + else: + raiseInvalid("Invalid type description: " & element) + valid.add element proc reqQuotationOfQuotations*(i: var MinInterpreter, a: var MinValue) = a = i.pop@@ -203,116 +218,25 @@ for s in a.qVal:
if not s.isNumber: raiseInvalid("A quotation of numbers is required on the stack") -proc reqIntAndQuotation*(i: var MinInterpreter, a, b: var MinValue) = - a = i.pop - b = i.pop - if not (a.isInt and b.isQuotation): - raiseInvalid("An integer and a quotation are required on the stack") - -proc reqTwoNumbers*(i: var MinInterpreter, a, b: var MinValue) = - a = i.pop - b = i.pop - if not (a.isNumber and b.isNumber): - raiseInvalid("Two numbers are required on the stack") - 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 reqIntAndString*(i: var MinInterpreter, b, a: var MinValue) = - b = i.pop - a = i.pop - if not (a.isString and b.isInt): - raiseInvalid("A string and a number are required on the stack") - -proc reqString*(i: var MinInterpreter, a: var MinValue) = - a = i.pop - if not a.isString: - raiseInvalid("A string is required on the stack") - -proc reqStringLikeAndQuotation*(i: var MinInterpreter, a, q: var MinValue) = - a = i.pop - q = i.pop - if not a.isStringLike or not q.isQuotation: - raiseInvalid("A string or symbol and a quotation are required on the stack") - -proc reqQuotationAndString*(i: var MinInterpreter, q, a: var MinValue) = - q = i.pop - a = i.pop - if not a.isString or not q.isQuotation: - raiseInvalid("A string and a quotation are required on the stack") - -proc reqQuotationAndStringLike*(i: var MinInterpreter, q, a: var MinValue) = - q = i.pop - a = i.pop - if not a.isStringLike or not q.isQuotation: - raiseInvalid("A quotation and a string or a symbol are required on the stack") - 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 reqStringLike*(i: var MinInterpreter, a: var MinValue) = - a = i.pop - if not a.isStringLike: - raiseInvalid("A quoted symbol or a string is required on the stack") - -proc reqTwoStrings*(i: var MinInterpreter, a, b: var MinValue) = - a = i.pop - b = i.pop - if not a.isString or not b.isString: - raiseInvalid("Two strings are required on the stack") - -proc reqTwoStringLike*(i: var MinInterpreter, a, b: var MinValue) = - a = i.pop - b = i.pop - if not a.isStringLike or not b.isStringLike: - raiseInvalid("Two symbols or strings are required on the stack") - -proc reqThreeStrings*(i: var MinInterpreter, a, b, c: var MinValue) = - a = i.pop - b = i.pop - c = i.pop - if not a.isString or not b.isString or not c.isString: - raiseInvalid("Three strings are required on the stack") - -proc reqTwoQuotations*(i: var MinInterpreter, a, b: var MinValue) = - a = i.pop - b = i.pop - if not a.isQuotation or not b.isQuotation: - raiseInvalid("Two quotations are required on the stack") - 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") -proc reqThreeQuotations*(i: var MinInterpreter, a, b, c: var MinValue) = - a = i.pop - b = i.pop - c = i.pop - if not a.isQuotation or not b.isQuotation or not c.isQuotation: - raiseInvalid("Three quotations are required on the stack") - -proc reqFourQuotations*(i: var MinInterpreter, a, b, c, d: var MinValue) = - a = i.pop - b = i.pop - c = i.pop - d = i.pop - if not a.isQuotation or not b.isQuotation or not c.isQuotation or not d.isQuotation: - raiseInvalid("Four quotations are required on the stack") - proc reqTwoSimilarTypesNonSymbol*(i: var MinInterpreter, a, b: var MinValue) = a = i.pop b = i.pop if not ((a.kind == a.kind or (a.isNumber and a.isNumber)) and not a.isSymbol): raiseInvalid("Two non-symbol values of similar type are required on the stack") - -proc reqDictionary*(i: In, q: var MinValue) = - q = i.pop - if not q.isDictionary: - raiseInvalid("An dictionary is required on the stack")
@@ -63,6 +63,21 @@
proc newSym*(s: string): MinValue = return MinValue(kind: minSymbol, symVal: s) +proc typeName*(v: MinValue): string = + case v.kind: + of minInt: + return "int" + of minFloat: + return "float" + of minQuotation: + return "quot" + of minString: + return "string" + of minSymbol: + return "sym" + of minBool: + return "bool" + # Get string value from string or quoted symbol proc getString*(v: MinValue): string =
@@ -17,48 +17,49 @@ proc crypto_module*(i: In)=
let def = i.define() def.symbol("md5") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.getMD5.newVal def.symbol("sha1") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push compute(s.getString).toHex.newVal def.symbol("sha224") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push computeSHA224(s.getString).hex.toLowerAscii.newVal def.symbol("sha256") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push computeSHA256(s.getString).hex.toLowerAscii.newVal def.symbol("sha384") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push computeSHA384(s.getString).hex.toLowerAscii.newVal def.symbol("sha512") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push computeSHA512(s.getString).hex.toLowerAscii.newVal def.symbol("encode") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.encode.newVal def.symbol("decode") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.decode.newVal def.symbol("aes") do (i: In): - var s, k: MinValue - i.reqTwoStrings k, s + let vals = i.expect("'sym", "'sym") + let k = vals[0] + let s = vals[1] var ctx: AESContext var text = s.getString var length = text.len
@@ -10,35 +10,37 @@ ../core/utils,
../core/fileutils proc fs_module*(i: In) = + let def = i.define() + def.symbol("mtime") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.getLastModificationTime.toSeconds.newVal def.symbol("atime") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.getLastAccessTime.toSeconds.newVal def.symbol("ctime") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.getCreationTime.toSeconds.newVal def.symbol("hidden?") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.isHidden.newVal def.symbol("fsize") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.getFileSize.newVal def.symbol("fstats") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] let fi = s.getString.getFileInfo var info = newSeq[MinValue](0).newVal(i.scope) info.qVal.add @["name".newSym, s].newVal(i.scope)@@ -54,13 +56,13 @@ info.qVal.add @["mtime".newSym, fi.lastWriteTime.toSeconds.newVal].newVal(i.scope)
i.push info def.symbol("ftype") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.getFileInfo.kind.filetype.newVal def.symbol("fperms") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.getFilePermissions.unixPermissions.newVal def.finalize("fs")
@@ -52,8 +52,9 @@ fatal $$a
quit(100) def.symbol("column-print") do (i: In): - var n, q: MinValue - i.reqIntAndQuotation n, q + let vals = i.expect("int", "quot") + let n = vals[0] + let q = vals[1] var c = 0 for s in q.qVal: c.inc@@ -71,15 +72,15 @@ var ed = initEditor()
i.push ed.password("Enter Password: ").newVal def.symbol("ask") do (i: In): - var s: MinValue var ed = initEditor() - i.reqString s + let vals = i.expect("string") + let s = vals[0] i.push ed.readLine(s.getString & ": ").newVal def.symbol("confirm") do (i: In): - var s: MinValue var ed = initEditor() - i.reqString s + let vals = i.expect("string") + let s = vals[0] proc confirm(): bool = let answer = ed.readLine(s.getString & " [yes/no]: ") if answer.match("^y(es)?$", "i"):@@ -92,9 +93,10 @@ return confirm()
i.push confirm().newVal def.symbol("choose") do (i: In): - var q, s: MinValue var ed = initEditor() - i.reqStringLikeAndQuotation s, q + let vals = i.expect("'sym", "quot") + let s = vals[0] + var q = vals[1] if q.qVal.len <= 0: raiseInvalid("No choices to display") stdout.writeLine(s.getString)@@ -127,18 +129,20 @@ def.symbol("print!") do (i: In):
i.pop.print def.symbol("fread") do (i: In): - var a: MinValue - i.reqString a + let vals = i.expect("string") + let a = vals[0] i.push newVal(a.strVal.readFile) def.symbol("fwrite") do (i: In): - var a, b: MinValue - i.reqTwoStrings a, b + let vals = i.expect("string", "string") + let a = vals[0] + let b = vals[1] a.strVal.writeFile(b.strVal) def.symbol("fappend") do (i: In): - var a, b: MinValue - i.reqTwoStrings a, b + let vals = i.expect("string", "string") + let a = vals[0] + let b = vals[1] var f:File discard f.open(a.strVal, fmAppend) f.write(b.strVal)
@@ -40,34 +40,34 @@ scope = scope.parent
i.push q.newVal(i.scope) def.symbol("module-symbols") do (i: In): - var m: MinValue - i.reqQuotation m + let vals = i.expect("quot") + let m = vals[0] var q = newSeq[MinValue](0) for s in m.scope.symbols.keys: q.add s.newVal i.push q.newVal(i.scope) def.symbol("module-sigils") do (i: In): - var m: MinValue - i.reqQuotation m + let vals = i.expect("quot") + let m = vals[0] var q = newSeq[MinValue](0) for s in m.scope.sigils.keys: q.add s.newVal i.push q.newVal(i.scope) def.symbol("from-json") do (i: In): - var s: MinValue - i.reqString s + let vals = i.expect("string") + let s = vals[0] i.push i.fromJson(s.getString.parseJson) def.symbol("to-json") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect "quot" + let q = vals[0] i.push(($((%q).pretty)).newVal) def.symbol("loglevel") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] var str = s.getString echo "Log level: ", setLogLevel(str)@@ -77,9 +77,9 @@
# Language constructs def.symbol("define") do (i: In): - var sym: MinValue - i.reqStringLike sym - var q1 = i.pop # existing (auto-quoted) + let vals = i.expect("'sym", "a") + let sym = vals[0] + var q1 = vals[1] # existing (auto-quoted) var symbol: string if not q1.isQuotation: q1 = @[q1].newVal(i.scope)@@ -92,9 +92,9 @@ raiseUndefined("Attempting to redefine sealed symbol '$1'" % [symbol])
i.scope.symbols[symbol] = MinOperator(kind: minValOp, val: q1, sealed: false) def.symbol("bind") do (i: In): - var sym: MinValue - i.reqStringLike sym - var q1 = i.pop # existing (auto-quoted) + let vals = i.expect("'sym", "a") + let sym = vals[0] + var q1 = vals[1] # existing (auto-quoted) var symbol: string if not q1.isQuotation: q1 = @[q1].newVal(i.scope)@@ -105,29 +105,30 @@ if not res:
raiseUndefined("Attempting to bind undefined symbol: " & symbol) def.symbol("delete") do (i: In): - var sym: MinValue - i.reqStringLike sym + let vals = i.expect("'sym") + let sym = vals[0] let res = i.scope.delSymbol(sym.getString) if not res: raiseUndefined("Attempting to delete undefined symbol: " & sym.getString) def.symbol("module") do (i: In): - var code, name: MinValue - i.reqStringLike name - i.reqQuotation code + let vals = i.expect("'sym", "quot") + let name = vals[0] + var code = vals[1] code.filename = i.filename i.unquote(code) info("[module] $1 ($2 symbols)" % [name.getString, $code.scope.symbols.len]) i.scope.symbols[name.getString] = MinOperator(kind: minValOp, val: @[code].newVal(i.scope)) def.symbol("import") do (i: In): - var mdl, rawName: MinValue + var vals = i.expect("'sym") + let rawName = vals[0] var name: string - i.reqStringLike rawName name = rawName.getString var op = i.scope.getSymbol(name) i.apply(op) - i.reqQuotation mdl + vals = i.expect("quot") + let mdl = vals[0] info("[import] Importing: $1 ($2 symbols, $3 sigils)" % [name, $mdl.scope.symbols.len, $mdl.scope.sigils.len]) for sym, val in mdl.scope.symbols.pairs: if i.scope.symbols.hasKey(sym) and i.scope.symbols[sym].sealed:@@ -141,13 +142,13 @@ i.debug "[import] $1" % [sig]
i.scope.sigils[sig] = val def.symbol("eval") do (i: In): - var s: MinValue - i.reqString s + let vals = i.expect("string") + let s = vals[0] i.eval s.strVal def.symbol("load") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] var file = s.getString if not file.endsWith(".min"): file = file & ".min"@@ -158,8 +159,9 @@ raiseInvalid("File '$1' does not exists." % file)
i.load file def.symbol("with") do (i: In): - var qscope, qprog: MinValue - i.reqTwoQuotations qscope, qprog + let vals = i.expect("quot", "quot") + var qscope = vals[0] + let qprog = vals[1] if qscope.qVal.len > 0: # System modules are empty quotes and don't need to be unquoted i.unquote(qscope)@@ -168,8 +170,9 @@ for v in qprog.qVal:
i.push v def.symbol("publish") do (i: In): - var qscope, str: MinValue - i.reqQuotationAndStringLike qscope, str + let vals = i.expect("quot", "'sym") + let qscope = vals[0] + let str = vals[1] let sym = str.getString if qscope.scope.symbols.hasKey(sym) and qscope.scope.symbols[sym].sealed: raiseUndefined("Attempting to redefine sealed symbol '$1'" % [sym])@@ -185,8 +188,8 @@ i.scope = origscope
qscope.scope.symbols[sym] = MinOperator(kind: minProcOp, prc: op) def.symbol("source") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] let str = s.getString let sym = i.scope.getSymbol(str) if sym.kind == minValOp:@@ -195,9 +198,9 @@ else:
raiseInvalid("No source available for native symbol '$1'." % str) def.symbol("call") do (i: In): - var symbol, q: MinValue - i.reqStringLike symbol - i.reqQuotation q + let vals = i.expect("'sym", "quot") + let symbol = vals[0] + let q = vals[1] let s = symbol.getString let origScope = i.scope i.scope = q.scope@@ -206,16 +209,16 @@ i.apply(sym)
i.scope = origScope def.symbol("raise") do (i: In): - var err: MinValue - i.reqDictionary err + let vals = i.expect("dict") + let err = vals[0] if err.dhas("error".newSym) and err.dhas("message".newSym): raiseRuntime("($1) $2" % [err.dget("error".newVal).getString, err.dget("message".newVal).getString], err.qVal) else: raiseInvalid("Invalid error dictionary") def.symbol("format-error") do (i: In): - var err: MinValue - i.reqDictionary err + let vals = i.expect("dict") + let err = vals[0] if err.dhas("error".newSym) and err.dhas("message".newSym): var msg: string var list = newSeq[MinValue]()@@ -237,8 +240,8 @@ else:
raiseInvalid("Invalid error dictionary") def.symbol("try") do (i: In): - var prog: MinValue - i.reqQuotation prog + let vals = i.expect("quot") + let prog = vals[0] if prog.qVal.len == 0: raiseInvalid("Quotation must contain at least one element") var code = prog.qVal[0]@@ -280,19 +283,22 @@ if hasFinally:
i.unquote(final) def.symbol("quote") do (i: In): - let a = i.pop + let vals = i.expect("a") + let a = vals[0] i.push @[a].newVal(i.scope) def.symbol("unquote") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + var q = vals[0] i.unquote(q) # Conditionals def.symbol("if") do (i: In): - var fpath, tpath, check: MinValue - i.reqThreeQuotations fpath, tpath, check + let vals = i.expect("quot", "quot", "quot") + var fpath = vals[0] + var tpath = vals[1] + var check = vals[2] var stack = i.stack i.unquote(check) let res = i.pop@@ -305,8 +311,9 @@ else:
i.unquote(fpath) def.symbol("when") do (i: In): - var tpath, check: MinValue - i.reqTwoQuotations tpath, check + let vals = i.expect("quot", "quot") + var tpath = vals[0] + var check = vals[1] var stack = i.stack i.unquote(check) let res = i.pop@@ -317,8 +324,9 @@ if res.boolVal == true:
i.unquote(tpath) def.symbol("unless") do (i: In): - var tpath, check: MinValue - i.reqTwoQuotations tpath, check + let vals = i.expect("quot", "quot") + var tpath = vals[0] + var check = vals[1] var stack = i.stack i.unquote(check) let res = i.pop@@ -334,8 +342,8 @@ # ((< 3) ("Smaller than 3" put!))
# ((true) ("Exactly 3" put!)) # ) case def.symbol("case") do (i: In): - var cases: MinValue - i.reqQuotation cases + let vals = i.expect("quot") + var cases = vals[0] if cases.qVal.len == 0: raiseInvalid("Empty case operator") var k = 0@@ -360,23 +368,26 @@
# Loops def.symbol("foreach") do (i: In): - var prog, list: MinValue - i.reqTwoQuotations prog, list + let vals = i.expect("quot", "quot") + var prog = vals[0] + var list = vals[1] for litem in list.qVal: i.push litem i.unquote(prog) def.symbol("times") do (i: In): - var t, prog: MinValue - i.reqIntAndQuotation t, prog + let vals = i.expect("int", "quot") + var t = vals[0] + var prog = vals[1] if t.intVal < 1: raiseInvalid("A non-zero natural number is required") for c in 1..t.intVal: i.unquote(prog) def.symbol("while") do (i: In): - var d, b: MinValue - i.reqTwoQuotations d, b + let vals = i.expect("quot", "quot") + var d = vals[0] + var b = vals[1] for e in b.qVal: i.push e i.unquote(b)@@ -390,8 +401,11 @@
# Other def.symbol("linrec") do (i: In): - var r2, r1, t, p: MinValue - i.reqFourQuotations r2, r1, t, p + let vals = i.expect("quot", "quot", "quot", "quot") + var r2 = vals[0] + var r1 = vals[1] + var t = vals[2] + var p = vals[3] proc linrec(i: In, p, t, r1, r2: var MinValue) = i.unquote(p) var check = i.pop@@ -409,8 +423,8 @@
# Save/load symbols def.symbol("save-symbol") do (i: In): - var s:MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] let sym = s.getString let op = i.scope.getSymbol(sym) if op.kind == minProcOp:@@ -420,8 +434,8 @@ json[sym] = %op.val
MINSYMBOLS.writeFile(json.pretty) def.symbol("load-symbol") do (i: In): - var s:MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] let sym = s.getString let json = MINSYMBOLS.readFile.parseJson if not json.hasKey(sym):@@ -437,8 +451,8 @@ q.add k.newVal
i.push q.newVal(i.scope) def.symbol("remove-symbol") do (i: In): - var s:MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] let sym = s.getString var json = MINSYMBOLS.readFile.parseJson if not json.hasKey(sym):@@ -447,31 +461,31 @@ json.delete(sym)
MINSYMBOLS.writeFile(json.pretty) def.symbol("seal") do (i: In): - var sym: MinValue - i.reqStringLike sym + let vals = i.expect("'sym") + let sym = vals[0] var s = i.scope.getSymbol(sym.getString) s.sealed = true i.scope.setSymbol(sym.getString, s) def.symbol("unseal") do (i: In): - var sym: MinValue - i.reqStringLike sym + let vals = i.expect("'sym") + let sym = vals[0] var s = i.scope.getSymbol(sym.getString) s.sealed = false i.scope.setSymbol(sym.getString, s, true) def.symbol("quote-bind") do (i: In): - var s, m: MinValue - i.reqString(s) - m = i.pop + let vals = i.expect("string", "a") + let s = vals[0] + let m = vals[1] i.push @[m].newVal(i.scope) i.push s i.push "bind".newSym def.symbol("quote-define") do (i: In): - var s, m: MinValue - i.reqString(s) - m = i.pop + let vals = i.expect("string", "a") + let s = vals[0] + let m = vals[1] i.push @[m].newVal(i.scope) i.push s i.push "define".newSym@@ -503,8 +517,8 @@
# Sigils def.sigil("'") do (i: In): - var s: MinValue - i.reqString s + let vals = i.expect("string") + let s = vals[0] i.push(@[s.strVal.newSym].newVal(i.scope)) def.sigil(":") do (i: In):
@@ -85,23 +85,26 @@
# Boolean Logic def.symbol("not") do (i: In): - var b: MinValue - i.reqBool b + let vals = i.expect("bool") + let b = vals[0] i.push newVal(not b.boolVal) def.symbol("and") do (i: In): - var a, b: MinValue - i.reqTwoBools a, b + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] i.push newVal(a.boolVal and b.boolVal) def.symbol("or") do (i: In): - var a, b: MinValue - i.reqTwoBools a, b + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] i.push newVal(a.boolVal or b.boolVal) def.symbol("xor") do (i: In): - var a, b: MinValue - i.reqTwoBools a, b + 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):
@@ -14,8 +14,9 @@
let def = i.define() def.symbol("+") do (i: In): - var a, b: MinValue - i.reqTwoNumbers a, b + 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)@@ -28,8 +29,9 @@ else:
i.push newVal(a.floatVal + b.intVal.float) def.symbol("-") do (i: In): - var a, b: MinValue - i.reqTwoNumbers a, b + let vals = i.expect("num", "num") + let a = vals[0] + let b = vals[1] if a.isInt: if b.isInt: i.push newVal(b.intVal - a.intVal)@@ -42,8 +44,9 @@ else:
i.push newVal(b.intVal.float - a.floatVal) def.symbol("*") do (i: In): - var a, b: MinValue - i.reqTwoNumbers a, b + 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)@@ -56,8 +59,9 @@ else:
i.push newVal(a.floatVal * b.intVal.float) def.symbol("/") do (i: In): - var a, b: MinValue - i.reqTwoNumbers a, b + let vals = i.expect("num", "num") + let a = vals[0] + let b = vals[1] if a.isInt: if b.isInt: i.push newVal(b.intVal.int / a.intVal.int)@@ -70,38 +74,40 @@ else:
i.push newVal(b.intVal.float / a.floatVal) def.symbol("random") do (i: In): - var n: MinValue - i.reqInt n + let vals = i.expect("int") + let n = vals[0] i.push n.intVal.int.random.newVal def.symbol("div") do (i: In): - var a, b: MinValue - i.reqTwoInts b, a + let vals = i.expect("int", "int") + let b = vals[0] + let a = vals[1] i.push(newVal(a.intVal div b.intVal)) def.symbol("mod") do (i: In): - var a, b: MinValue - i.reqTwoInts b, a + let vals = i.expect("int", "int") + let b = vals[0] + let a = vals[1] i.push(newVal(a.intVal mod b.intVal)) def.symbol("succ") do (i: In): - var n: MinValue - i.reqInt n + let vals = i.expect("int") + let n = vals[0] i.push newVal(n.intVal + 1) def.symbol("pred") do (i: In): - var n: MinValue - i.reqInt n + let vals = i.expect("int") + let n = vals[0] i.push newVal(n.intVal - 1) def.symbol("even?") do (i: In): - var n: MinValue - i.reqInt n + let vals = i.expect("int") + let n = vals[0] i.push newVal(n.intVal mod 2 == 0) def.symbol("odd?") do (i: In): - var n: MinValue - i.reqInt n + let vals = i.expect("int") + let n = vals[0] i.push newVal(n.intVal mod 2 != 0) def.symbol("sum") do (i: In):
@@ -15,50 +15,52 @@
let def = i.define() def.symbol("concat") do (i: In): - var q1, q2: MinValue - i.reqTwoQuotations q1, q2 + let vals = i.expect("quot", "quot") + let q1 = vals[0] + let q2 = vals[1] let q = q2.qVal & q1.qVal i.push q.newVal(i.scope) def.symbol("first") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + let q = vals[0] if q.qVal.len == 0: raiseOutOfBounds("Quotation is empty") i.push q.qVal[0] def.symbol("rest") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + let q = vals[0] if q.qVal.len == 0: raiseOutOfBounds("Quotation is empty") i.push q.qVal[1..q.qVal.len-1].newVal(i.scope) def.symbol("append") do (i: In): - var q: MinValue - i.reqQuotation q - let v = i.pop + let vals = i.expect("quot", "a") + let q = vals[0] + let v = vals[1] i.push newVal(q.qVal & v, i.scope) def.symbol("prepend") do (i: In): - var q: MinValue - i.reqQuotation q - let v = i.pop + let vals = i.expect("quot", "a") + let q = vals[0] + let v = vals[1] i.push newVal(v & q.qVal, i.scope) def.symbol("get") do (i: In): - var index, q: MinValue - i.reqIntAndQuotation index, q + let vals = i.expect("int", "quot") + let index = vals[0] + let q = vals[1] let ix = index.intVal if q.qVal.len < ix or ix < 0: raiseOutOfBounds("Index out of bounds") i.push q.qVal[ix.int] def.symbol("set") do (i: In): - var val, index, q: MinValue - i.reqInt index - val = i.pop - i.reqQuotation q + let vals = i.expect("int", "a", "quot") + let index = vals[0] + let val = vals[1] + let q = vals[2] let ix = index.intVal if q.qVal.len < ix or ix < 0: raiseOutOfBounds("Index out of bounds")@@ -66,8 +68,9 @@ q.qVal[ix.int] = val
i.push q def.symbol("remove") do (i: In): - var index, q: MinValue - i.reqIntAndQuotation index, q + let vals = i.expect("int", "quot") + let index = vals[0] + let q = vals[1] let ix = index.intVal if q.qVal.len < ix or ix < 0: raiseOutOfBounds("Index out of bounds")@@ -79,10 +82,10 @@ res.add q.qVal[x]
i.push res.newVal(i.scope) def.symbol("insert") do (i: In): - var val, index, q: MinValue - i.reqInt index - val = i.pop - i.reqQuotation q + let vals = i.expect("int", "a", "quot") + let index = vals[0] + let val = vals[1] + let q = vals[2] let ix = index.intVal if q.qVal.len < ix or ix < 0: raiseOutOfBounds("Index out of bounds")@@ -94,20 +97,20 @@ res.add q.qVal[x]
i.push res.newVal(i.scope) def.symbol("size") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + let q = vals[0] i.push q.qVal.len.newVal def.symbol("in?") do (i: In): - i.reqStackSize(2) - let v = i.pop - var q: MinValue - i.reqQuotation q + let vals = i.expect("a", "quot") + let v = vals[0] + let q = vals[1] i.push q.qVal.contains(v).newVal def.symbol("map") do (i: In): - var prog, list: MinValue - i.reqTwoQuotations prog, list + let vals = i.expect("quot", "quot") + var prog = vals[0] + let list = vals[1] var res = newSeq[MinValue](0) for litem in list.qVal: i.push litem@@ -116,21 +119,22 @@ res.add i.pop
i.push res.newVal(i.scope) def.symbol("apply") do (i: In): - var prog: MinValue - i.reqQuotation prog + let vals = i.expect("quot") + let prog = vals[0] i.apply prog def.symbol("reverse") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + let q = vals[0] var res = newSeq[MinValue](0) for c in countdown(q.qVal.len-1, 0): res.add q.qVal[c] i.push res.newVal(i.scope) def.symbol("filter") do (i: In): - var filter, list: MinValue - i.reqTwoQuotations filter, list + let vals = i.expect("quot", "quot") + var filter = vals[0] + let list = vals[1] var res = newSeq[MinValue](0) for e in list.qVal: i.push e@@ -141,8 +145,9 @@ res.add e
i.push res.newVal(i.scope) def.symbol("reject") do (i: In): - var filter, list: MinValue - i.reqTwoQuotations filter, list + let vals = i.expect("quot", "quot") + var filter = vals[0] + let list = vals[1] var res = newSeq[MinValue](0) for e in list.qVal: i.push e@@ -153,8 +158,9 @@ res.add e
i.push res.newVal(i.scope) def.symbol("any?") do (i: In): - var filter, list: MinValue - i.reqTwoQuotations filter, list + let vals = i.expect("quot", "quot") + var filter = vals[0] + let list = vals[1] for e in list.qVal: i.push e i.unquote(filter)@@ -165,8 +171,9 @@ return
i.push false.newVal def.symbol("all?") do (i: In): - var filter, list: MinValue - i.reqTwoQuotations filter, list + let vals = i.expect("quot", "quot") + var filter = vals[0] + let list = vals[1] for e in list.qVal: i.push e i.unquote(filter)@@ -177,8 +184,9 @@ break
i.push true.newVal def.symbol("sort") do (i: In): - var cmp, list: MinValue - i.reqTwoQuotations cmp, list + let vals = i.expect("quot", "quot") + var cmp = vals[0] + let list = vals[1] var i2 = i var minCmp = proc(a, b: MinValue): int {.closure.}= i2.push a@@ -197,15 +205,18 @@ sort[MinValue](qList, minCmp)
i.push qList.newVal(i.scope) def.symbol("shorten") do (i: In): - var n, q: MinValue - i.reqIntAndQuotation n, q + let vals = i.expect("int", "quot") + let n = vals[0] + let q = vals[1] if n.intVal > q.qVal.len: raiseInvalid("Quotation is too short") i.push q.qVal[0..n.intVal.int-1].newVal(i.scope) def.symbol("find") do (i: In): - var s, test, result: MinValue - i.reqTwoQuotations test, s + let vals = i.expect("quot", "quot") + var test = vals[0] + let s = vals[1] + var result: MinValue var res = -1 var c = 0 for el in s.qVal:@@ -219,10 +230,10 @@ c.inc
i.push res.newVal def.symbol("reduce") do (i: In): - var s, q, acc: MinValue - i.reqQuotation q - acc = i.pop - i.reqQuotation s + let vals = i.expect("quot", "a", "quot") + var q = vals[0] + var acc = vals[1] + let s = vals[2] for el in s.qVal: i.push acc i.push el@@ -231,13 +242,15 @@ acc = i.pop
i.push acc def.symbol("map-reduce") do (i: In): - var s, map, red, acc: MinValue - i.reqThreeQuotations red, map, s + let vals = i.expect("quot", "quot", "quot") + var red = vals[0] + var map = vals[1] + let s = vals[2] if s.qVal.len == 0: raiseInvalid("Quotation must have at least one element") i.push s.qVal[0] i.unquote map - acc = i.pop + var acc = i.pop for ix in 1..s.qVal.len-1: i.push s.qVal[ix] i.unquote map@@ -247,8 +260,9 @@ acc = i.pop
i.push acc def.symbol("partition") do (i: In): - var s, test: MinValue - i.reqTwoQuotations test, s + let vals = i.expect("quot", "quot") + var test = vals[0] + var s = vals[1] var tseq = newSeq[MinValue](0) var fseq = newSeq[MinValue](0) for el in s.qVal:@@ -263,10 +277,10 @@ i.push tseq.newVal(i.scope)
i.push fseq.newVal(i.scope) def.symbol("slice") do (i: In): - var start, finish, q: MinValue - i.reqInt finish - i.reqInt start - i.reqQuotation q + let vals = i.expect("int", "int", "quot") + let finish = vals[0] + let start = vals[1] + let q = vals[2] let st = start.intVal let fn = finish.intVal if st < 0 or fn > q.qVal.len-1:@@ -277,8 +291,8 @@ let rng = q.qVal[st.int..fn.int]
i.push rng.newVal(i.scope) def.symbol("harvest") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + let q = vals[0] var res = newSeq[MinValue](0) for el in q.qVal: if el.isQuotation and el.qVal.len == 0:@@ -287,8 +301,8 @@ res.add el
i.push res.newVal(i.scope) def.symbol("flatten") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + let q = vals[0] var res = newSeq[MinValue](0) for el in q.qVal: if el.isQuotation:@@ -301,38 +315,38 @@
# Operations on dictionaries def.symbol("dhas?") do (i: In): - var d, k: MinValue - i.reqStringLike k - i.reqDictionary d + let vals = i.expect("'sym", "dict") + let k = vals[0] + let d = vals[1] i.push d.dhas(k).newVal def.symbol("dget") do (i: In): - var d, k: MinValue - i.reqStringLike k - i.reqDictionary d + let vals = i.expect("'sym", "dict") + let k = vals[0] + let d = vals[1] i.push d.dget(k) def.symbol("dset") do (i: In): - var d, k: MinValue - i.reqStringLike k - let m = i.pop - i.reqDictionary d + let vals = i.expect("'sym", "a", "dict") + let k = vals[0] + let m = vals[1] + let d = vals[2] i.push i.dset(d, k, m) def.symbol("ddel") do (i: In): - var d, k: MinValue - i.reqStringLike k - i.reqDictionary d + let vals = i.expect("'sym", "dict") + let k = vals[0] + let d = vals[1] i.push i.ddel(d, k) def.symbol("keys") do (i: In): - var d: MinValue - i.reqDictionary d + let vals = i.expect("dict") + let d = vals[0] i.push i.keys(d) def.symbol("values") do (i: In): - var d: MinValue - i.reqDictionary d + let vals = i.expect("dict") + let d = vals[0] i.push i.values(d) def.finalize("seq")
@@ -20,32 +20,29 @@ def.symbol("get-stack") do (i: In):
i.push i.stack.newVal(i.scope) def.symbol("set-stack") do (i: In): - var q: MinValue - i.reqQuotation q + let vals = i.expect("quot") + let q = vals[0] i.stack = q.qVal def.symbol("id") do (i: In): discard def.symbol("pop") do (i: In): - if i.stack.len < 1: - raiseEmptyStack() discard i.pop def.symbol("dup") do (i: In): i.push i.peek def.symbol("dip") do (i: In): - var q: MinValue - i.reqQuotation q - let v = i.pop + let vals = i.expect("quot", "a") + var q = vals[0] + let v = vals[1] i.unquote(q) i.push v def.symbol("nip") do (i: In): - var a, b: MinValue - a = i.pop - b = i.pop + let vals = i.expect("a", "a") + let a = vals[0] i.push a def.symbol("cleave") do (i: In):@@ -71,60 +68,60 @@ i.unquote(s1)
count.dec def.symbol("keep") do (i: In): - var q: MinValue - i.reqQuotation q - let v = i.pop + let vals = i.expect("quot", "a") + var q = vals[0] + let v = vals[1] i.push v i.unquote(q) i.push v def.symbol("swap") do (i: In): - i.reqStackSize 2 - let a = i.pop - let b = i.pop + let vals = i.expect("a", "a") + let a = vals[0] + let b = vals[1] i.push a i.push b def.symbol("over") do (i: In): - i.reqStackSize 2 - let a = i.pop - let b = i.pop + let vals = i.expect("a", "a") + let a = vals[0] + let b = vals[1] i.push b i.push a i.push b def.symbol("pick") do (i: In): - i.reqStackSize 3 - let a = i.pop - let b = i.pop - let c = i.pop + let vals = i.expect("a", "a", "a") + let a = vals[0] + let b = vals[1] + let c = vals[2] i.push c i.push b i.push a i.push c def.symbol("rollup") do (i: In): - i.reqStackSize 3 - let first = i.pop - let second = i.pop - let third = i.pop + let vals = i.expect("a", "a", "a") + let first = vals[0] + let second = vals[1] + let third = vals[2] i.push first i.push second i.push third def.symbol("rolldown") do (i: In): - i.reqStackSize 3 - let first = i.pop - let second = i.pop - let third = i.pop + let vals = i.expect("a", "a", "a") + let first = vals[0] + let second = vals[1] + let third = vals[2] i.push second i.push first i.push third def.symbol("cons") do (i: In): - var q: MinValue - i.reqQuotation q - let v = i.pop + let vals = i.expect("quot", "a") + let q = vals[0] + let v = vals[1] q.qVal = @[v] & q.qVal i.push q@@ -133,8 +130,9 @@ i.push "swap".newSym
i.push "cons".newSym def.symbol("sip") do (i: In): - var a, b: MinValue - i.reqTwoQuotations a, b + let vals = i.expect("quot", "quot") + var a = vals[0] + let b = vals[1] i.push b i.unquote(a) i.push b
@@ -14,8 +14,9 @@ proc str_module*(i: In) =
let def = i.define() def.symbol("interpolate") do (i: In): - var s, q: MinValue - i.reqQuotationAndString q, s + let vals = i.expect("quot", "string") + var q = vals[0] + let s = vals[1] var strings = newSeq[string](0) for el in q.qVal: strings.add $$el@@ -23,64 +24,68 @@ let res = s.strVal % strings
i.push res.newVal def.symbol("strip") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.strip.newVal def.symbol("split") do (i: In): - var sep, s: MinValue - i.reqTwoStrings sep, s + let vals = i.expect("string", "string") + let sep = vals[0] + let s = vals[1] var q = newSeq[MinValue](0) for e in s.strVal.split(sep.strVal): q.add e.newVal i.push q.newVal(i.scope) def.symbol("join") do (i: In): - var q, s: MinValue - i.reqStringLikeAndQuotation s, q + let vals = i.expect("'sym", "quot") + let s = vals[0] + let q = vals[1] i.push q.qVal.mapIt($$it).join(s.getString).newVal def.symbol("length") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.len.newVal def.symbol("lowercase") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.toLowerAscii.newVal def.symbol("uppercase") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.toUpperAscii.newVal def.symbol("capitalize") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.capitalizeAscii.newVal def.symbol("titleize") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.split(" ").mapIt(it.capitalizeAscii).join(" ").newVal def.symbol("repeat") do (i: In): - var s, n: MinValue - i.reqIntAndString n, s + let vals = i.expect("int", "string") + let n = vals[0] + let s = vals[1] i.push s.getString.repeat(n.intVal).newVal def.symbol("indent") do (i: In): - var s, n: MinValue - i.reqIntAndString n, s + let vals = i.expect("int", "string") + let n = vals[0] + let s = vals[1] i.push s.getString.indent(n.intVal).newVal def.symbol("string") do (i: In): - var s = i.pop + let s = i.pop i.push(($$s).newVal) def.symbol("bool") do (i: In): - var v = i.pop + let v = i.pop let strcheck = (v.isString and (v.getString == "false" or v.getString == "")) let intcheck = v.isInt and v.intVal == 0 let floatcheck = v.isFloat and v.floatVal == 0@@ -92,7 +97,7 @@ else:
i.push true.newVal def.symbol("int") do (i: In): - var s = i.pop + let s = i.pop if s.isString: i.push s.getString.parseInt.newVal elif s.isFloat:@@ -108,7 +113,7 @@ else:
raiseInvalid("Cannot convert a quotation to an integer.") def.symbol("float") do (i: In): - var s = i.pop + let s = i.pop if s.isString: i.push s.getString.parseFloat.newVal elif s.isInt:@@ -124,8 +129,9 @@ else:
raiseInvalid("Cannot convert a quotation to float.") def.symbol("search") do (i: In): - var reg, str: MinValue - i.reqTwoStrings reg, str + let vals = i.expect("string", "string") + let reg = vals[0] + let str = vals[1] var matches = str.strVal.search(reg.strVal) var res = newSeq[MinValue](matches.len) for i in 0..matches.len-1:@@ -133,21 +139,25 @@ res[i] = matches[i].newVal
i.push res.newVal(i.scope) def.symbol("match") do (i: In): - var reg, str: MinValue - i.reqTwoStrings reg, str + let vals = i.expect("string", "string") + let reg = vals[0] + let str = vals[1] if str.strVal.match(reg.strVal): i.push true.newVal else: i.push false.newVal def.symbol("replace") do (i: In): - var s_replace, reg, s_find: MinValue - i.reqThreeStrings s_replace, reg, s_find + let vals = i.expect("string", "string", "string") + let s_replace = vals[0] + let reg = vals[1] + let s_find = vals[2] i.push sgregex.replace(s_find.strVal, reg.strVal, s_replace.strVal).newVal def.symbol("regex") do (i: In): - var reg, str: MinValue - i.reqTwoStrings reg, str + let vals = i.expect("string", "string") + let reg = vals[0] + let str = vals[1] let results = str.strVal =~ reg.strVal var res = newSeq[MinValue](0) for r in results:
@@ -27,55 +27,56 @@ def.symbol("..") do (i: In):
i.push newVal(getCurrentDir().parentDir.unix) def.symbol("cd") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] f.getString.setCurrentDir def.symbol("ls") do (i: In): - var a: MinValue - i.reqStringLike a + let vals = i.expect("'sym") + let a = vals[0] var list = newSeq[MinValue](0) for i in walkDir(a.getString): list.add newVal(i.path.unix) i.push list.newVal(i.scope) def.symbol("ls-r") do (i: In): - var a: MinValue - i.reqStringLike a + let vals = i.expect("'sym") + let a = vals[0] var list = newSeq[MinValue](0) for i in walkDirRec(a.getString): list.add newVal(i.unix) i.push list.newVal(i.scope) def.symbol("system") do (i: In): - var a: MinValue - i.reqStringLike a + let vals = i.expect("'sym") + let a = vals[0] i.push execShellCmd(a.getString).newVal def.symbol("run") do (i: In): - var cmd: MinValue - i.reqStringLike cmd + let vals = i.expect("'sym") + let cmd = vals[0] let res = execCmdEx(cmd.getString) i.push @[@["output".newSym, res.output.newVal].newVal(i.scope), @["code".newSym, res.exitCode.newVal].newVal(i.scope)].newVal(i.scope) def.symbol("get-env") do (i: In): - var a: MinValue - i.reqStringLike a + let vals = i.expect("'sym") + let a = vals[0] i.push a.getString.getEnv.newVal def.symbol("put-env") do (i: In): - var key, value: MinValue - i.reqTwoStringLike key, value + let vals = i.expect("'sym", "'sym") + let key = vals[0] + let value = vals[1] key.getString.putEnv value.getString def.symbol("env?") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.existsEnv.newVal def.symbol("which") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.findExe.newVal def.symbol("os") do (i: In):@@ -85,23 +86,23 @@ def.symbol("cpu") do (i: In):
i.push hostCPU.newVal def.symbol("exists?") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] i.push newVal(f.getString.fileExists or f.getString.dirExists) def.symbol("file?") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] i.push f.getString.fileExists.newVal def.symbol("dir?") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] i.push f.getString.dirExists.newVal def.symbol("rm") do (i: In): - var v: MinValue - i.reqStringLike v + let vals = i.expect("'sym") + let v = vals[0] let f = v.getString if f.existsFile: f.removeFile@@ -111,8 +112,9 @@ else:
raiseInvalid("File '$1' does not exist." % f) def.symbol("cp") do (i: In): - var a, b: MinValue - i.reqTwoStringLike a, b + let vals = i.expect("'sym", "'sym") + let a = vals[0] + let b = vals[1] let src = b.getString var dest = a.getString if src.dirExists:@@ -126,8 +128,9 @@ else:
copyFileWithPermissions src, dest def.symbol("mv") do (i: In): - var a, b: MinValue - i.reqTwoStringLike a, b + let vals = i.expect("'sym", "'sym") + let a = vals[0] + let b = vals[1] let src = b.getString var dest = a.getString if dest.dirExists:@@ -135,48 +138,51 @@ dest = dest / src.extractFilename
moveFile src, dest def.symbol("rmdir") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] f.getString.removeDir def.symbol("mkdir") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] f.getString.createDir def.symbol("sleep") do (i: In): - var ms: MinValue - i.reqInt ms + let vals = i.expect("int") + let ms = vals[0] sleep ms.intVal.int def.symbol("chmod") do (i: In): - var s, perms: MinValue - i.reqIntAndString perms, s + let vals = i.expect("int", "string") + let perms = vals[0] + let s = vals[1] s.getString.setFilePermissions(perms.intVal.toFilePermissions) def.symbol("symlink?") do (i: In): - var s: MinValue - i.reqStringLike s + let vals = i.expect("'sym") + let s = vals[0] i.push s.getString.symlinkExists.newVal def.symbol("symlink") do (i: In): - var src, dest: MinValue - i.reqTwoStringLike dest, src + let vals = i.expect("'sym", "'sym") + let dest = vals[0] + let src = vals[0] src.getString.createSymlink dest.getString def.symbol("hardlink") do (i: In): - var src, dest: MinValue - i.reqTwoStringLike dest, src + let vals = i.expect("'sym", "'sym") + let dest = vals[0] + let src = vals[0] src.getString.createHardlink dest.getString def.symbol("filename") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] i.push f.getString.extractFilename.unix.newVal def.symbol("dirname") do (i: In): - var f: MinValue - i.reqStringLike f + let vals = i.expect("'sym") + let f = vals[0] i.push f.getString.parentDir.unix.newVal def.symbol("$") do (i: In):@@ -199,13 +205,15 @@ i.push("run".newSym)
when not defined(lite): def.symbol("unzip") do (i: In): - var f, dir: MinValue - i.reqTwoStringLike dir, f + let vals = i.expect("'sym", "'sym") + let dir = vals[0] + let f = vals[1] miniz.unzip(f.getString, dir.getString) def.symbol("zip") do (i: In): - var files, file: MinValue - i.reqStringLikeAndQuotation file, files + let vals = i.expect("'sym", "quot") + let file = vals[0] + let files = vals[1] miniz.zip(files.qVal.mapIt(it.getString), file.getString) def.finalize("sys")
@@ -20,8 +20,8 @@ def.symbol("now") do (i: In):
i.push epochTime().newVal def.symbol("timeinfo") do (i: In): - var t: MinValue - i.reqNumber t + let vals = i.expect("num") + let t = vals[0] var time: Time if t.kind == minInt: time = t.intVal.fromSeconds@@ -40,8 +40,8 @@ info.qVal.add @["second".newSym, tinfo.second.newVal].newVal(i.scope)
i.push info def.symbol("datetime") do (i: In): - var t: MinValue - i.reqNumber t + let vals = i.expect("num") + let t = vals[0] var time: Time if t.kind == minInt: time = t.intVal.fromSeconds@@ -50,9 +50,9 @@ time = t.floatVal.fromSeconds
i.push time.getLocalTime.format("yyyy-MM-dd'T'HH:mm:ss'Z'").newVal def.symbol("tformat") do (i: In): - var t, s: MinValue - i.reqString s - i.reqNumber t + let vals = i.expect("string", "num") + let s = vals[0] + let t = vals[1] var time: Time if t.kind == minInt: time = t.intVal.fromSeconds
@@ -195,8 +195,8 @@ ed.completionCallback = proc(ed: LineEditor): seq[string] =
return ed.getCompletions(symbols) # evaluate prompt i.apply(i.scope.getSymbol("prompt")) - var v: MinValue - i.reqString(v) + let vals = i.expect("string") + let v = vals[0] let prompt = v.getString() line = ed.readLine(prompt) i.parser.bufpos = 0
@@ -68,4 +68,4 @@
("3.678" float 3.678 ==) assert report - clear-stack+ clear-stack