all repos — min @ 6fb163209ee6fae653bb55026668e381bd61cb49

A small but practical concatenative programming language.

Attempting to generate binary file.
h3rald h3rald@h3rald.com
Sat, 05 Aug 2023 13:23:52 +0200
commit

6fb163209ee6fae653bb55026668e381bd61cb49

parent

5e58077a7bc559feca2864ce213fc4bdca000958

3 files changed, 46 insertions(+), 30 deletions(-)

jump to
M .gitignore.gitignore

@@ -21,3 +21,4 @@ mintool

mintool.nim test.min .DS_Store +*.bmin
M min.nimmin.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.nimminpkg/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())