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