JustAnotherJAPL/src/backend/serializer.nim

84 lines
2.4 KiB
Nim
Raw Normal View History

# Copyright 2020 Mattia Giambirtone
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import meta/ast
import meta/errors
import meta/bytecode
import ../config
import strformat
import strutils
import nimSHA2
import times
export ast
type
Serializer* = ref object
file: string
filename: string
chunk: Chunk
Serialized* = ref object
## Wrapper returned by
## the Serializer.read*
## procedures to store
## metadata
fileHash*: string
japlVer*: string
japlBranch*: string
commitHash*: string
chunk*: Chunk
proc error(self: Serializer, message: string) =
## Raises a formatted SerializationError exception
raise newException(SerializationError, &"A fatal error occurred while serializing '{self.filename}' -> {message}")
proc initSerializer*(): Serializer =
new(result)
result.file = ""
result.filename = ""
result.chunk = nil
proc dumpBytes*(self: Serializer, chunk: Chunk, file, filename: string): seq[byte] =
## Dumps the given bytecode and file to a sequence of bytes and returns it.
## The file's content is needed to compute its SHA256 hash.
self.file = file
self.filename = filename
self.chunk = chunk
for c in "JAPL_BYTECODE":
result.add(byte(c))
result.add(byte(len(JAPL_BRANCH)))
for c in JAPL_BRANCH:
result.add(byte(c))
if len(JAPL_COMMIT_HASH) != 40:
self.error("the commit hash must be exactly 40 characters long")
for c in JAPL_COMMIT_HASH:
result.add(byte(c))
for b in cast[array[8, uint8]](getTime().toUnixFloat().int()):
result.add(b)
for c in computeSHA256(file):
result.add(byte(c))
proc dumpHex*(self: Serializer, chunk: Chunk, file, filename: string): string =
## Wrapper of dumpBytes that returns a hex string (using strutils.toHex)
## instead of a seq[byte]
for b in self.dumpBytes(chunk, file, filename):
result.add(toHex(b))