core/utils.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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
import tables, strutils, macros, critbits
import types, parser, interpreter
proc isSymbol*(s: MinValue): bool =
return s.kind == minSymbol
proc isQuotation*(s: MinValue): bool =
return s.kind == minQuotation
proc isString*(s: MinValue): bool =
return s.kind == minString
proc isFloat*(s: MinValue): bool =
return s.kind == minFloat
proc isInt*(s: MinValue): bool =
return s.kind == minInt
proc isNumber*(s: MinValue): bool =
return s.kind == minInt or s.kind == minFloat
proc isBool*(s: MinValue): bool =
return s.kind == minBool
proc newVal*(s: string): MinValue =
return MinValue(kind: minString, strVal: s)
proc newVal*(s: cstring): MinValue =
return MinValue(kind: minString, strVal: $s)
proc newVal*(q: seq[MinValue]): MinValue =
return MinValue(kind: minQuotation, qVal: q)
proc newVal*(s: int): MinValue =
return MinValue(kind: minInt, intVal: s)
proc newVal*(s: float): MinValue =
return MinValue(kind: minFloat, floatVal: s)
proc newVal*(s: bool): MinValue =
return MinValue(kind: minBool, boolVal: s)
proc isStringLike*(s: MinValue): bool =
return s.isSymbol or s.isString
proc getString*(v: MinValue): string =
if v.isSymbol:
return v.symVal
elif v.isString:
return v.strVal
proc warn*(s: string) =
stderr.writeLine s
proc previous*(scope: ref MinScope): ref MinScope =
if scope.parent.isNil:
return ROOT
else:
return scope.parent
proc define*(name: string): ref MinScope =
var scope = new MinScope
scope.name = name
scope.parent = INTERPRETER.scope
return scope
proc symbol*(scope: ref MinScope, sym: string, p: MinOperator): ref MinScope =
scope.symbols[sym] = p
#if not scope.parent.isNil:
# scope.parent.symbols[scope.name & ":" & sym] = p
return scope
proc sigil*(scope: ref MinScope, sym: string, p: MinOperator): ref MinScope =
scope.previous.sigils[sym] = p
return scope
proc finalize*(scope: ref MinScope) =
var mdl = newSeq[MinValue](0).newVal
mdl.scope = scope
mdl.scope.previous.symbols[scope.name] = proc(i: In) =
i.evaluating = true
i.push mdl
i.evaluating = false
template `<-`*[T](target, source: var T) =
shallowCopy target, source
template alias*[T](varname: untyped, value: var T) =
var varname {.inject.}: type(value)
shallowCopy varname, value
# Validators
proc reqInt*(i: var MinInterpreter, a: var MinValue) =
a = i.pop
if not a.isInt:
raise MinInvalidError(msg: "An integer is required on the stack")
proc reqQuotation*(i: var MinInterpreter, a: var MinValue) =
a = i.pop
if not a.isQuotation:
raise MinInvalidError(msg: "A quotation is required on the stack")
proc reqString*(i: var MinInterpreter, a: var MinValue) =
a = i.pop
if not a.isString:
raise MinInvalidError(msg: "A string is required on the stack")
proc reqStringOrQuotation*(i: var MinInterpreter, a: var MinValue) =
a = i.pop
if not a.isQuotation and not a.isString:
raise MinInvalidError(msg: "A quotation or a string is required on the stack")
proc reqTwoStrings*(i: var MinInterpreter, a, b: var MinValue) =
a = i.pop
b = i.pop
if not a.isString or not b.isString:
raise MinInvalidError(msg: "Two strings are required on the stack")
proc reqThreeStrings*(i: var MinInterpreter, a, b, c: var MinValue) =
a = i.pop
b = i.pop
c = i.pop
if not a.isString or not b.isString or not c.isString:
raise MinInvalidError(msg: "Three strings are required on the stack")
proc reqTwoQuotations*(i: var MinInterpreter, a, b: var MinValue) =
a = i.pop
b = i.pop
if not a.isQuotation or not b.isQuotation:
raise MinInvalidError(msg: "Two quotations are required on the stack")
proc reqThreeQuotations*(i: var MinInterpreter, a, b, c: var MinValue) =
a = i.pop
b = i.pop
c = i.pop
if not a.isQuotation or not b.isQuotation or not c.isQuotation:
raise MinInvalidError(msg: "Three quotations are required on the stack")
proc reqFourQuotations*(i: var MinInterpreter, a, b, c, d: var MinValue) =
a = i.pop
b = i.pop
c = i.pop
d = i.pop
if not a.isQuotation or not b.isQuotation or not c.isQuotation or not d.isQuotation:
raise MinInvalidError(msg: "Four quotations are required on the stack")
|