all repos — min @ b3373bcf448301a1c575888dfba0981701998164

A small but practical concatenative programming language.

Added implementation for symbol binding (def, bind, :).
h3rald h3rald@h3rald.com
Sun, 09 Nov 2014 20:20:59 +0100
commit

b3373bcf448301a1c575888dfba0981701998164

parent

cbf56e3665bf42ab3419e54c4356c7aeffaa0877

3 files changed, 66 insertions(+), 60 deletions(-)

jump to
M interpreter.niminterpreter.nim

@@ -125,7 +125,7 @@ result = my.filename

proc errorMsg*(my: TMinParser, msg: string): string = assert(my.kind == eMinError) - result = "$1 [$2, $3] ERROR - $4" % [ + result = "$1 [l:$2, c:$3] ERROR - $4" % [ my.filename, $getLine(my), $getColumn(my), msg] proc errorMsg*(my: TMinParser): string =
M primitives.nimprimitives.nim

@@ -1,52 +1,5 @@

import tables, strutils -import interpreter - -proc valueError(s: TMinValue, msg: string) = - stderr.writeln("$1 [$2, $3] Error - $4" %[s.file, $s.first, $s.last, msg]) - quit(1) - -proc peek(s: TMinStack, i = 1): TMinValue = - return s[s.len-i] - -proc expects(sym: string, reqs: openarray[string]) = - var i = 0 - var a: TMinValue - for r in reqs: - inc(i) - a = STACK.peek(i) - if r != "any" and a.kind != TYPES[r]: - a.valueError("$1: Value #$2 is not a $3" % [sym, $i, r]) - -template minsym(name: string, reqs: openarray[string], body: stmt): stmt = - SYMBOLS[name] = proc (val: TMinValue) = - let n_req = reqs.len - let n_found = STACK.len - if n_found < n_req: - val.valueError("$1: Not enough values on the stack (required: $2, found: $3)." % [name, $n_req, $n_found]) - name.expects reqs - body - -proc alias(newname, oldname) = - SYMBOLS[newname] = SYMBOLS[oldname] - -proc printMinValue(a: TMinValue) = - case a.kind: - of minSymbol: - stdout.write a.symVal - of minString: - stdout.write "\""&a.strVal&"\"" - of minInt: - stdout.write a.intVal - of minFloat: - stdout.write a.floatVal - of minQuotation: - stdout.write "[ " - for i in a.qVal: - printMinValue i - stdout.write " " - stdout.write "]" - -### SYMBOL DEFINITIONS ### +import interpreter, utils minsym "dup", ["any"]: STACK.add STACK.peek

@@ -68,21 +21,27 @@ minsym "i", []:

discard minsym "print", ["any"]: - let a = STACK[STACK.len-1] + let a = STACK.peek printMinValue a echo "" -minsym "alias", ["quotation", "quotation"]: +minsym "def", ["quotation", "any"]: var q = STACK.pop var v = STACK.pop if q.qVal.len != 1 or q.qVal[0].kind != minSymbol: - q.valueError("alias: First quoted symbol not found on the stack.") - let newalias = q.qVal[0].symVal - if v.qVal.len != 1 or v.qVal[0].kind != minSymbol: - q.valueError("alias: Second quoted symbol '$1' not found on the stack") - let orig = v.qVal[0].symVal - if SYMBOLS.haskey orig: - SYMBOLS[newalias] = SYMBOLS[orig] - else: - v.valueError("alias: Unknown symbol '$1'" % [orig]) + q.valueError("def: Definition quotation not found on the stack.") + if v.qVal.len != 1 or q.qVal[0].kind != minSymbol: + v.valueError("def: Value quotation not found on the stack.") + let defname = q.qVal[0].symVal + let value = v.qVal[0] + case value.kind: + of minSymbol: + if SYMBOLS.hasKey value.symVal: + SYMBOLS[defname] = SYMBOLS[value.symVal] + else: + value.valueError("Undefined symbol: '"&value.symVal&"'") + else: + SYMBOLS[defname] = proc(v: TMinValue) = STACK.add value +minalias ":", "def" +minalias "bind", "def"
A utils.nim

@@ -0,0 +1,47 @@

+import tables, strutils +import interpreter + +proc printMinValue*(a: TMinValue) = + case a.kind: + of minSymbol: + stdout.write a.symVal + of minString: + stdout.write "\""&a.strVal&"\"" + of minInt: + stdout.write a.intVal + of minFloat: + stdout.write a.floatVal + of minQuotation: + stdout.write "[ " + for i in a.qVal: + printMinValue i + stdout.write " " + stdout.write "]" + +proc valueError*(s: TMinValue, msg: string) = + stderr.writeln("$1 [c:$3] Error - $4" %[s.file, $s.first, $s.last, msg]) + quit(1) + +proc peek*(s: TMinStack, i = 1): TMinValue = + return s[s.len-i] + +proc expects*(sym: string, reqs: openarray[string]) = + var i = 0 + var a: TMinValue + for r in reqs: + inc(i) + a = STACK.peek(i) + if r != "any" and a.kind != TYPES[r]: + a.valueError("$1: Value #$2 is not a $3" % [sym, $i, r]) + +template minsym*(name: string, reqs: openarray[string], body: stmt): stmt = + SYMBOLS[name] = proc (val: TMinValue) = + let n_req = reqs.len + let n_found = STACK.len + if n_found < n_req: + val.valueError("$1: Not enough values on the stack (required: $2, found: $3)." % [name, $n_req, $n_found]) + name.expects reqs + body + +proc minalias*(newname: string, oldname: string) = + SYMBOLS[newname] = SYMBOLS[oldname]