Initial work on simplifying the type system and added more VM utility functions

This commit is contained in:
Nocturn9x 2022-05-02 23:19:17 +02:00
parent 1ceedde8e9
commit 4d41054120
2 changed files with 66 additions and 81 deletions

View File

@ -17,65 +17,39 @@ type
ObjectKind* = enum ObjectKind* = enum
## Enumeration of Peon ## Enumeration of Peon
## types ## types
objFloat, objInt, objBool, Int8, UInt8, Int16, UInt16, Int32,
objNil, objNan, objInf, UInt32, Int64, UInt64, Float32, Float64,
objString Char, Byte, String, Function, CustomType,
PeonObject* = ref object of RootObj Nil, Nan, Bool, Inf
PeonObject* = object
## A generic Peon object ## A generic Peon object
kind*: ObjectKind case kind*: ObjectKind:
Nil* = ref object of PeonObject of Bool:
Nan* = ref object of PeonObject boolean*: bool
Inf* = ref object of PeonObject of Inf:
positive*: bool positive*: bool
Bool* = ref object of PeonObject of Byte:
value*: bool `byte`*: byte
Int8* = ref object of PeonObject of Int8:
value*: int8 tiny*: uint8
Int16* = ref object of PeonObject of UInt8:
value*: int16 uTiny*: uint8
Int32* = ref object of PeonObject of Int16:
value*: int32 short*: int16
Int64* = ref object of PeonObject of UInt16:
value*: int64 uShort*: uint16
UInt8* = ref object of PeonObject of Int32:
value*: uint8 `int`*: int32
UInt16* = ref object of PeonObject of UInt32:
value*: uint16 uInt*: uint32
UInt32* = ref object of PeonObject of Int64:
value*: uint32 long*: int64
UInt64* = ref object of PeonObject of UInt64:
value*: uint64 uLong*: uint64
Float32* = ref object of PeonObject of Nil, Nan:
value*: float32 discard
Float64* = ref object of PeonObject of CustomType:
value*: float64 fields*: seq[PeonObject]
else:
# We create a type alias for floats discard # TODO
# and integers depending on the current
# platform's native sizes
when sizeof(int) == 8:
type Int = Int64
elif sizeof(int) == 4:
type Int = Int32
elif sizeof(int) == 2:
type Int = Int16
else:
type Int = Int8
when sizeof(float) == 8:
type Float = Float64
else:
type Float = Float32
# Simple constructors for builtin types
proc newNil*: Nil = Nil(kind: objNil)
proc newNan*: Nan = Nan(kind: objNan)
proc newInf*(positive: bool): Inf = Inf(kind: objInf, positive: positive)
proc newBool*(value: bool): Bool = Bool(kind: objBool, value: value)
proc newInt*(value: int): Int = Int(kind: objInt, value: value)
proc newFloat*(value: float): Float = Float(kind: objFloat, value: value)
proc `$`*(self: PeonObject): string =
## Stringifies a peon object

View File

@ -31,12 +31,12 @@ type
proc initCache*(self: PeonVM) = proc initCache*(self: PeonVM) =
## Initializes the VM's ## Initializes the VM's
## singletons cache ## singletons cache
self.cache[0] = newNil() self.cache[0] = PeonObject(kind: Nil)
self.cache[1] = newBool(true) self.cache[1] = PeonObject(kind: Bool, boolean: true)
self.cache[2] = newBool(false) self.cache[2] = PeonObject(kind: Bool, boolean: false)
self.cache[3] = newInf(true) self.cache[3] = PeonObject(kind: ObjectKind.Inf, positive: true)
self.cache[4] = newInf(false) self.cache[4] = PeonObject(kind: ObjectKind.Inf, positive: false)
self.cache[5] = newNan() self.cache[5] = PeonObject(kind: ObjectKind.Nan)
proc newPeonVM*: PeonVM = proc newPeonVM*: PeonVM =
@ -50,30 +50,30 @@ proc newPeonVM*: PeonVM =
for _ in 0..<INITIAL_STACK_SIZE: for _ in 0..<INITIAL_STACK_SIZE:
result.stack.add(result.cache[0]) result.stack.add(result.cache[0])
# Getters for singleton types (they are cached!) ## Getters for singleton types (they are cached!)
proc getNil*(self: PeonVM): Nil = Nil(self.cache[0]) proc getNil*(self: PeonVM): PeonObject = self.cache[0]
proc getBool*(self: PeonVM, value: bool): Bool = proc getBool*(self: PeonVM, value: bool): PeonObject =
if value: if value:
return Bool(self.cache[1]) return self.cache[1]
return Bool(self.cache[2]) return self.cache[2]
proc getInf*(self: PeonVM, positive: bool): Inf = proc getInf*(self: PeonVM, positive: bool): PeonObject =
if positive: if positive:
return types.Inf(self.cache[3]) return self.cache[3]
return types.Inf(self.cache[4]) return self.cache[4]
proc getNan*(self: PeonVM): Nan = types.Nan(self.cache[5]) proc getNan*(self: PeonVM): PeonObject = self.cache[5]
# Stack primitives ## Stack primitives
proc push(self: PeonVM, obj: PeonObject) = proc push(self: PeonVM, obj: PeonObject) =
## Pushes a Peon object onto the ## Pushes a Peon object onto the
## stack ## stack
if self.sp >= self.stack.high(): if self.sp >= self.stack.high():
for _ in 0..self.stack.len(): for _ in 0..self.stack.len():
self.stack.add(newNil()) self.stack.add(self.getNil())
self.stack[self.sp] = obj self.stack[self.sp] = obj
inc(self.sp) inc(self.sp)
@ -103,7 +103,7 @@ proc readShort(self: PeonVM): uint16 =
copyMem(result.addr, unsafeAddr(arr), sizeof(arr)) copyMem(result.addr, unsafeAddr(arr), sizeof(arr))
proc readBytes(self: PeonVM): uint32 = proc readLong(self: PeonVM): uint32 =
## Reads three bytes from the ## Reads three bytes from the
## bytecode and returns them ## bytecode and returns them
## as an unsigned 32 bit ## as an unsigned 32 bit
@ -114,14 +114,25 @@ proc readBytes(self: PeonVM): uint32 =
copyMem(result.addr, unsafeAddr(arr), sizeof(arr)) copyMem(result.addr, unsafeAddr(arr), sizeof(arr))
proc readConstant(self: PeonVM): PeonObject = proc readLongLong(self: PeonVM): uint64 =
## Reads 4 bytes from the
## bytecode and returns them
## as an unsigned 64 bit
## integer
var arr: array[4, uint8]
copyMem(result.addr, unsafeAddr(arr), sizeof(arr))
proc readInt64(self: PeonVM): PeonObject =
## Reads a constant from the ## Reads a constant from the
## chunk's constant table ## chunk's constant table and
## returns a Peon object. Assumes
## the constant's type is an Int64
var arr = [self.readByte(), self.readByte(), self.readByte()] var arr = [self.readByte(), self.readByte(), self.readByte()]
var idx: int var idx: int
copyMem(idx.addr, arr.addr, sizeof(arr)) copyMem(idx.addr, arr.addr, sizeof(arr))
# TODO # TODO
# result = self.chunk.consts[idx] # result = PeonObject()
proc dispatch*(self: PeonVM) = proc dispatch*(self: PeonVM) =