all repos — min @ 858875a85585b3454faad998cbd19119a8ebf011

A small but practical concatenative programming language.

refactor(validation) Added reqTwo/Three/FourQuotations.
h3rald h3rald@h3rald.com
Sat, 04 Jun 2016 22:39:59 +0200
commit

858875a85585b3454faad998cbd19119a8ebf011

parent

cd4618ea4341f335294e06d37e72ee1c49f2aeed

2 files changed, 65 insertions(+), 71 deletions(-)

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

@@ -89,13 +89,30 @@ template alias*[T](varname: untyped, value: var T) =

var varname {.inject.}: type(value) shallowCopy varname, value +# Validators + +proc reqQuotation*(i: var MinInterpreter, a: var MinValue) = + a = i.pop + if not a.isQuotation: + raise MinInvalidError(msg: "A quotation is 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: raise MinInvalidError(msg: "Two quotations are required on the stack") -proc reqQuotation*(i: var MinInterpreter, a: var MinValue) = +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: + raise MinInvalidError(msg: "Four quotations are required on the stack") + +proc reqFourQuotations*(i: var MinInterpreter, a, b, c, d: var MinValue) = a = i.pop - if not a.isQuotation: - raise MinInvalidError(msg: "A quotation is required on the stack") + 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: + raise MinInvalidError(msg: "Four quotations are required on the stack")
M lib/lang.nimlib/lang.nim

@@ -328,18 +328,14 @@ i.reqQuotation q

i.push q.qVal.contains(v).newVal .symbol("map") do (i: In): - var prog = i.pop - let list = i.pop - if prog.isQuotation and list.isQuotation: - i.push newVal(newSeq[MinValue](0)) - for litem in list.qVal: - i.push litem - i.unquote("<map-quotation>", prog) - i.apply("swap") - i.apply("append") - else: - i.error(errIncorrect, "Two quotations are required on the stack") - return + var prog, list: MinValue + i.reqTwoQuotations prog, list + i.push newVal(newSeq[MinValue](0)) + for litem in list.qVal: + i.push litem + i.unquote("<map-quotation>", prog) + i.apply("swap") + i.apply("append") .symbol("times") do (i: In): let t = i.pop

@@ -352,71 +348,52 @@ i.error errIncorrect, "An integer and a quotation are required on the stack"

return .symbol("ifte") do (i: In): - var fpath = i.pop - var tpath = i.pop - var check = i.pop + var fpath, tpath, check: MinValue + i.reqThreeQuotations fpath, tpath, check var stack = i.copystack - if check.isQuotation and tpath.isQuotation and fpath.isQuotation: - i.unquote("<ifte-check>", check) - let res = i.pop - i.stack = stack - if res.isBool and res.boolVal == true: - i.unquote("<ifte-true>", tpath) - else: - i.unquote("<ifte-false>", fpath) + i.unquote("<ifte-check>", check) + let res = i.pop + i.stack = stack + if res.isBool and res.boolVal == true: + i.unquote("<ifte-true>", tpath) else: - i.error(errIncorrect, "Three quotations are required on the stack") - return + i.unquote("<ifte-false>", fpath) .symbol("while") do (i: In): - var d = i.pop - var b = i.pop - if b.isQuotation and d.isQuotation: - i.push b.qVal + var d, b: MinValue + i.reqTwoQuotations d, b + i.push b.qVal + i.unquote("<while-check>", b) + var check = i.pop + while check.isBool and check.boolVal == true: + i.unquote("<while-quotation>", d) i.unquote("<while-check>", b) - var check = i.pop - while check.isBool and check.boolVal == true: - i.unquote("<while-quotation>", d) - i.unquote("<while-check>", b) - check = i.pop - else: - i.error(errIncorrect, "Two quotations are required on the stack") - return + check = i.pop .symbol("filter") do (i: In): - var filter = i.pop - let list = i.pop + var filter, list: MinValue + i.reqTwoQuotations filter, list var res = newSeq[MinValue](0) - if filter.isQuotation and list.isQuotation: - for e in list.qVal: - i.push e - i.unquote("<filter-check>", filter) - var check = i.pop - if check.isBool and check.boolVal == true: - res.add e - i.push res.newVal - else: - i.error(errIncorrect, "Two quotations are required on the stack") - return + for e in list.qVal: + i.push e + i.unquote("<filter-check>", filter) + var check = i.pop + if check.isBool and check.boolVal == true: + res.add e + i.push res.newVal .symbol("linrec") do (i: In): - var r2 = i.pop - var r1 = i.pop - var t = i.pop - var p = i.pop - if p.isQuotation and t.isQuotation and r1.isQuotation and r2.isQuotation: - proc linrec(i: In, p, t, r1, r2: var MinValue) = - i.unquote("<linrec-predicate>", p) - var check = i.pop - if check.isBool and check.boolVal == true: - i.unquote("<linrec-true>", t) - else: - i.unquote("<linrec-r1>", r1) - i.linrec(p, t, r1, r2) - i.unquote("<linrec-r2>", r2) - i.linrec(p, t, r1, r2) - else: - i.error(errIncorrect, "Four quotations are required on the stack") - return + var r2, r1, t, p: MinValue + i.reqFourQuotations r2, r1, t, p + proc linrec(i: In, p, t, r1, r2: var MinValue) = + i.unquote("<linrec-predicate>", p) + var check = i.pop + if check.isBool and check.boolVal == true: + i.unquote("<linrec-true>", t) + else: + i.unquote("<linrec-r1>", r1) + i.linrec(p, t, r1, r2) + i.unquote("<linrec-r2>", r2) + i.linrec(p, t, r1, r2) .finalize()