Implemented first and rest.
h3rald h3rald@h3rald.com
Sun, 23 Nov 2014 14:51:19 +0100
2 files changed,
52 insertions(+),
23 deletions(-)
M
interpreter.nim
→
interpreter.nim
@@ -73,11 +73,10 @@ else:
i.error(errEmptyStack) proc dump*(i: TMinInterpreter) = - stdout.write "[ " for item in i.stack: item.print stdout.write " " - stdout.writeln "]" + stdout.writeln "" proc interpret*(i: var TMinInterpreter) = var val: TMinValue
M
primitives.nim
→
primitives.nim
@@ -1,48 +1,49 @@
import tables, strutils import parser, interpreter, utils +# Common stack operations + +minsym "i": + discard + minsym "pop": discard i.pop minsym "dup": i.push i.peek -minsym "swap": - let a = i.pop - let b = i.pop - i.push a - i.push b - -minsym "quote": - let a = i.pop - i.push TMinValue(kind: minQuotation, qVal: @[a]) - -minsym "unquote": +minsym "dip": let q = i.pop if not q.isQuotation: i.error errNoQuotation + let v = i.pop for item in q.qVal: - i.push item + i.push item + i.push v -minsym "i": - discard +minsym "swap": + let a = i.pop + let b = i.pop + i.push a + i.push b minsym "print": let a = i.peek a.print echo "" -minsym "dump": - i.dump +# Operations on quotations + +minsym "quote": + let a = i.pop + i.push TMinValue(kind: minQuotation, qVal: @[a]) -minsym "dip": +minsym "unquote": let q = i.pop if not q.isQuotation: i.error errNoQuotation - let v = i.pop for item in q.qVal: - i.push item - i.push v + i.push item minsym "cons": var q = i.pop@@ -52,6 +53,13 @@ i.error errNoQuotation
q.qVal.add v i.push q +# Operations on the whole stack + +minsym "dump": + i.dump + +# Operations on quotations or strings + minsym "concat": var q1 = i.pop var q2 = i.pop@@ -62,7 +70,27 @@ elif q1.isQuotation and q2.isQuotation:
let q = q2.qVal & q1.qVal i.push newQuotation(q) else: - i.error(errIncorrect, "Two quotations or two strings required on the stack") + i.error(errIncorrect, "Two quotations or two strings is required on the stack") + +minsym "first": + var q = i.pop + if q.isQuotation: + i.push q.qVal[0] + elif q.isString: + i.push newString($q.strVal[0]) + else: + i.error(errIncorrect, "A quotation or a string is required on the stack") + +minsym "rest": + var q = i.pop + if q.isQuotation: + i.push newQuotation(q.qVal[1..q.qVal.len-1]) + elif q.isString: + i.push newString(q.strVal[1..q.strVal.len-1]) + else: + i.error(errIncorrect, "A quotation or a string is required on the stack") + +# Arithmetic minsym "+": let a = i.pop@@ -137,6 +165,8 @@ elif b.isInt:
i.push newFloat(b.intVal.float / a.floatVal) else: i.error(errTwoNumbersRequired) + + minalias "&", "concat" minalias "%", "print"