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") |