Attempting to generate binary file.
h3rald h3rald@h3rald.com
Sat, 05 Aug 2023 13:23:52 +0200
3 files changed,
46 insertions(+),
30 deletions(-)
M
min.nim
→
min.nim
@@ -190,7 +190,7 @@
proc minFile*(filename: string, op = "interpret", main = true): seq[ string] {.discardable.} -proc compile*(i: In, s: Stream, main = true): seq[string] = +proc compile*(i: In, s: Stream, main = true): seq[string] {.discardable.} = if "nim".findExe == "": logging.error "Nim compiler not found, unable to compile." quit(7)@@ -222,20 +222,24 @@ except CatchableError:
discard i.close() -proc minStream(s: Stream, filename: string, op = "interpret", main = true): seq[ - string] {.discardable.} = +proc compileToBytecode*(i: In, s: Stream) = + let dotindex = i.filename.rfind(".") + let bminFile = i.filename[0..dotindex-1] & ".bnim" + try: + let bcode = i.rawBytecodeCompile() + writeFile(bminFile, bcode) + except CatchableError: + echo getCurrentExceptionMsg() + +proc minStream(s: Stream, filename: string, op = "interpret", main = true) = var i = newMinInterpreter(filename = filename) i.pwd = filename.parentDirEx if op == "interpret": i.interpret(s) - discard newSeq[string](0) elif op == "bytecode-compile": - i.open(s, i.filename) - discard i.parser.getToken() - let code = i.parser.compileToBytecode() - vm.printBytecode(code) + i.compileToBytecode(s) else: - discard i.compile(s, main) + i.compile(s, main) proc minStr*(buffer: string) = minStream(newStringStream(buffer), "input")
M
minpkg/core/vm.nim
→
minpkg/core/vm.nim
@@ -1,6 +1,7 @@
import strutils, - sequtils + sequtils, + logging import meta,@@ -9,8 +10,8 @@ parser,
interpreter, opcodes -proc newVM*(): MinVm = - result.interpreter = newMinInterpreter("<vm>") +proc toHex*(code: seq[byte]): string = + code.mapIt(it.toHex).join() proc bytecode(s: string, symbol = false): seq[byte] = result = newSeq[byte](0)@@ -21,18 +22,23 @@ result.add opStr.byte
for c in s: result.add c.ord.byte result.add opUndef.byte - + var t = "string" + if symbol: + t = "symbol" + logging.debug("$# {$#} $#" % [t, s, result.toHex]) when cpuEndian == littleEndian: proc bytecode(n: BiggestInt): seq[byte] = result = newSeq[byte](0) result.add opPushIn.byte result = result.concat(cast[array[0..7, byte]](n).toSeq) + logging.debug("integer {$#} $#" % [$n, result.toHex]) proc bytecode(n: BiggestFloat): seq[byte] = result = newSeq[byte](0) result.add opPushFl.byte result = result.concat(cast[array[0..7, byte]](n).toSeq) + logging.debug("float {$#} $#" % [$n, result.toHex]) else: import algorithm@@ -41,35 +47,29 @@ result = newSeq[byte](0)
result.add opPushIn.byte result = result.concat(cast[array[0..7, byte]](n).toSeq) result.reverse() + logging.debug("integer {$#} $#" % [$n, result.toHex]) proc bytecode(n: BiggestFloat): seq[byte] = result = newSeq[byte](0) result.add opPushFl.byte result = result.concat(cast[array[0..7, byte]](n).toSeq) result.reverse() - + logging.debug("float {$#} $#" % [$n, result.toHex]) -proc compileToBytecode*(p: var MinParser): seq[byte] = - result = newSeq[byte](0) - result.add opHead.byte - for c in pkgName: - result.add c.ord.byte - let v = pkgVersion.split(".") - result.add v[0].parseInt.byte - result.add v[1].parseInt.byte - result.add v[2].parseInt.byte - result.add opUndef.byte - result.add opUndef.byte +proc generateBytecodeForToken*(p: var MinParser): seq[byte] = case p.token: of tkNull: result.add opPushNl.byte discard p.getToken() + logging.debug("null: ", opPushFa.byte.toHex) of tkTrue: result.add opPushTr.byte discard p.getToken() + logging.debug("true: ", opPushFa.byte.toHex) of tkFalse: result.add opPushFa.byte discard p.getToken() + logging.debug("false: ", opPushFa.byte.toHex) of tkInt: result = result.concat(p.a.parseInt.bytecode) p.a = ""@@ -89,10 +89,21 @@ discard p.getToken()
else: raiseUndefined(p, "Undefined value: '"&p.a&"'") - -proc printBytecode*(code: seq[byte]) = - for b in code: - stdout.write(b.toHex & " ") - stdout.writeLine("") +proc rawBytecodeCompile*(i: In, indent = ""): seq[byte] {.discardable.} = + result.add opHead.byte + for c in pkgName: + result.add c.ord.byte + let v = pkgVersion.split(".") + result.add v[0].parseInt.byte + result.add v[1].parseInt.byte + result.add v[2].parseInt.byte + result.add opUndef.byte + result.add opUndef.byte + logging.debug("header: ", result.toHex) + discard i.parser.getToken() + while i.parser.token != tkEof: + if i.trace.len == 0: + i.stackcopy = i.stack + result = result.concat(i.parser.generateBytecodeForToken())