lib/quotations.nim
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
import tables
import
../core/types,
../core/parser,
../core/interpreter,
../core/utils
# Operations on quotations
minsym "quote", i:
let a = i.pop
i.push MinValue(kind: minQuotation, qVal: @[a])
minsym "unquote", i:
let q = i.pop
if not q.isQuotation:
i.error errNoQuotation
for item in q.qVal:
i.push item
minsym "cons", i:
var q = i.pop
let v = i.pop
if not q.isQuotation:
i.error errNoQuotation
q.qVal.add v
i.push q
minsym "at", i:
var index = i.pop
var q = i.pop
if index.isInt and q.isQuotation:
i.push q.qVal[index.intVal]
else:
i.error errIncorrect, "An integer and a quotation are required on the stack"
minsym "map", i:
let 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
for pitem in prog.qVal:
i.push pitem
i.apply("swap")
i.apply("cons")
else:
i.error(errIncorrect, "Two quotations are required on the stack")
minsym "times", i:
let t = i.pop
let prog = i.pop
if t.isInt and prog.isQuotation:
for c in 1..t.intVal:
for pitem in prog.qVal:
i.push pitem
else:
i.error errIncorrect, "An integer and a quotation are required on the stack"
minsym "ifte", i:
let fpath = i.pop
let tpath = i.pop
let check = i.pop
var stack = i.copystack
if check.isQuotation and tpath.isQuotation and fpath.isQuotation:
i.push check.qVal
let res = i.pop
i.stack = stack
if res.isBool and res.boolVal == true:
i.push tpath.qVal
else:
i.push fpath.qVal
else:
i.error(errIncorrect, "Three quotations are required on the stack")
minsym "while", i:
let d = i.pop
let b = i.pop
if b.isQuotation and d.isQuotation:
i.push b.qVal
var check = i.pop
while check.isBool and check.boolVal == true:
i.push d.qVal
i.push b.qVal
check = i.pop
else:
i.error(errIncorrect, "Two quotations are required on the stack")
minsym "filter", i:
let filter = i.pop
let list = i.pop
var res = newSeq[MinValue](0)
if filter.isQuotation and list.isQuotation:
for e in list.qVal:
i.push e
i.push filter.qVal
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")
minsym "linrec", i:
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:
i.linrec(p, t, r1, r2)
else:
i.error(errIncorrect, "Four quotations are required on the stack")
|