refactor(OutOfBounds) Implemented bound checking.
h3rald h3rald@h3rald.com
Sun, 12 Jun 2016 12:14:03 +0200
5 files changed,
53 insertions(+),
29 deletions(-)
M
core/types.nim
→
core/types.nim
@@ -85,6 +85,7 @@ MinParsingError* = ref object of ValueError
MinUndefinedError* = ref object of ValueError MinInvalidError* = ref object of ValueError MinEmptyStackError* = ref object of ValueError + MinOutOfBoundsError* = ref object of ValueError MinRuntimeError* = ref object of SystemError qVal*: seq[MinValue]
M
core/utils.nim
→
core/utils.nim
@@ -97,6 +97,9 @@
proc raiseUndefined*(msg: string) = raise MinUndefinedError(msg: msg) +proc raiseOutOfBounds*(msg: string) = + raise MinOutOfBoundsError(msg: msg) + proc raiseRuntime*(msg: string, qVal: var seq[MinValue]) = raise MinRuntimeError(msg: msg, qVal: qVal)
M
lib/lang.nim
→
lib/lang.nim
@@ -202,12 +202,12 @@ finally:
if hasFinally: i.unquote("<try-finally>", final) - .symbol("counquote") do (i: In): + .symbol("multiunquote") do (i: In): var q: MinValue i.reqQuotation q let stack = i.copystack proc coroutine(i: MinInterpreter, c: int, results: ptr MinStack) {.routine.} = - i.unquote("<counquote>", q.qVal[c]) + i.unquote("<multiunquote>", q.qVal[c]) results[][c] = i.stack[0] var results = newSeq[MinValue](q.qVal.len) for c in 0..q.qVal.high:@@ -253,16 +253,24 @@ .symbol("first") do (i: In):
var q: MinValue i.reqStringOrQuotation q if q.isQuotation: + if q.qVal.len == 0: + raiseOutOfBounds("Quotation is empty") i.push q.qVal[0] elif q.isString: + if q.strVal.len == 0: + raiseOutOfBounds("String is empty") i.push newVal($q.strVal[0]) .symbol("rest") do (i: In): var q: MinValue i.reqStringOrQuotation q if q.isQuotation: + if q.qVal.len == 0: + raiseOutOfBounds("Quotation is empty") i.push newVal(q.qVal[1..q.qVal.len-1]) elif q.isString: + if q.strVal.len == 0: + raiseOutOfBounds("String is empty") i.push newVal(q.strVal[1..q.strVal.len-1]) .symbol("quote") do (i: In):@@ -291,6 +299,8 @@
.symbol("at") do (i: In): var index, q: MinValue i.reqIntAndQuotation index, q + if q.qVal.len-1 < index.intVal: + raiseOutOfBounds("Insufficient items in quotation") i.push q.qVal[index.intVal] .symbol("size") do (i: In):@@ -320,6 +330,8 @@
.symbol("times") do (i: In): var t, prog: MinValue i.reqIntAndQuotation t, prog + if t.intVal < 1: + raiseInvalid("A non-zero natural number is required") for c in 1..t.intVal: i.unquote("<times-quotation>", prog)
M
lib/prelude.min
→
lib/prelude.min
@@ -20,31 +20,33 @@ (load) (@) sigil
(":" split call) (%) sigil ; Aliases -'define :: -'bind :. -'import :# -'exit :quit -'== :eq -'!= :noteq -'> :gt -'< :lt -'>= :gte -'<= :lte -'put :echo -'system :! -'run :& -'getenv :$ -'pop :zap -'quote :unit -'quote :' -'unquote :i -'unquote :apply -'unquote :-> -'scope :=> -'filter :select -'clear :empty -'cons :prepend -'size :length +'define :: +'bind :. +'import :# +'exit :quit +'== :eq +'!= :noteq +'> :gt +'< :lt +'>= :gte +'<= :lte +'put :echo +'system :! +'run :& +'getenv :$ +'pop :zap +'quote :unit +'quote :' +'unquote :i +'unquote :apply +'unquote :-> +'multiunquote :multiapply +'multiunquote :->> +'scope :=> +'filter :select +'clear :empty +'cons :prepend +'size :length ; Mathematical Operators (1 +) :succ
M
tests/lang.min
→
tests/lang.min
@@ -3,7 +3,7 @@ #test
"lang" describe - (symbols size 163 ==) assert + (symbols size 165 ==) assert (sigils size 10 ==) assert@@ -101,12 +101,18 @@ (1 at)
) try "Test Message" ==) assert ( + ( + (() 1 at) + (1) + ) try 1 ==) assert + + ( ((dup 0 ==) (1 +) (dup 1 -) ( * ) linrec) :factorial ( (8 factorial) (12 factorial) (9 factorial) - ) counquote (40320 479001600 362880) ==) assert + ) ->> (40320 479001600 362880) ==) assert report ; Tidy up