trying to bring it into a compilable state

This commit is contained in:
Productive2 2020-10-23 00:31:39 +02:00
parent b3ff804296
commit d531386d6b
9 changed files with 145 additions and 208 deletions

View File

@ -15,9 +15,10 @@
import tables
import strutils
import meta/valuearray
import meta/tokenobject
import types/japlvalue
import meta/japlvalue
import types/stringtype
import types/functiontype
const FRAMES_MAX* = 400 # TODO: Inspect why the VM crashes if this exceeds 400
@ -91,15 +92,15 @@ proc delete*(self: CallFrame, idx: int) =
func stringify*(value: Value): string =
case value.kind:
of INTEGER:
of ValueType.Integer:
result = $value.toInt()
of DOUBLE:
of ValueType.Double:
result = $value.toFloat()
of BOOL:
of ValueType.Bool:
result = $value.toBool()
of NIL:
of ValueType.Nil:
result = "nil"
of OBJECT:
of ValueType.Object:
case value.obj.kind:
of ObjectType.String:
result = cast[ptr String](value.obj).stringify
@ -111,7 +112,7 @@ func stringify*(value: Value): string =
result = "nan"
of ValueType.Inf:
result = "inf"
of MINF:
of ValueType.Minf:
result = "-inf"
@ -131,16 +132,16 @@ proc hashFloat(f: float): uint32 =
# TODO: Move this into an hash() method for objects
proc hash*(value: Value): uint32 =
case value.kind:
of INTEGER:
of ValueType.Integer:
result = uint32 value.toInt()
of BOOL:
of ValueType.Bool:
if value.boolValue:
result = uint32 1
else:
result = uint32 0
of DOUBLE:
of ValueType.Double:
result = hashFloat(value.toFloat())
of OBJECT:
of ValueType.Object:
case value.obj.kind:
of ObjectType.String:
result = hash(cast[ptr String](value.obj))
@ -153,9 +154,9 @@ proc hash*(value: Value): uint32 =
# TODO: Move this into a bool() method for objects
func isFalsey*(value: Value): bool =
case value.kind:
of BOOL:
of ValueType.Bool:
result = not value.toBool()
of OBJECT:
of ValueType.Object:
case value.obj.kind:
of ObjectType.String:
result = cast[ptr String](value.obj).isFalsey()
@ -163,11 +164,11 @@ func isFalsey*(value: Value): bool =
result = cast[ptr Function](value.obj).isFalsey()
else:
result = isFalsey(value.obj)
of INTEGER:
of ValueType.Integer:
result = value.toInt() == 0
of DOUBLE:
of ValueType.Double:
result = value.toFloat() == 0.0
of NIL:
of ValueType.Nil:
result = true
of ValueType.Inf, ValueType.Minf:
result = false
@ -181,9 +182,9 @@ func typeName*(value: Value): string =
of ValueType.Bool, ValueType.Nil, ValueType.Double,
ValueType.Integer, ValueType.Nan, ValueType.Inf:
result = ($value.kind).toLowerAscii()
of MINF:
of ValueType.Minf:
result = "inf"
of OBJECT:
of ValueType.Object:
case value.obj.kind:
of ObjectType.String:
result = cast[ptr String](value.obj).typeName()
@ -198,15 +199,15 @@ proc valuesEqual*(a: Value, b: Value): bool =
result = false
else:
case a.kind:
of BOOL:
of ValueType.Bool:
result = a.toBool() == b.toBool()
of NIL:
of ValueType.Nil:
result = true
of INTEGER:
of ValueType.Integer:
result = a.toInt() == b.toInt()
of DOUBLE:
of ValueType.Double:
result = a.toFloat() == b.toFloat()
of OBJECT:
of ValueType.Object:
case a.obj.kind:
of ObjectType.String:
var a = cast[ptr String](a.obj)
@ -220,7 +221,7 @@ proc valuesEqual*(a: Value, b: Value): bool =
result = valuesEqual(a.obj, b.obj)
of ValueType.Inf:
result = b.kind == ValueType.Inf
of MINF:
of ValueType.Minf:
result = b.kind == ValueType.Minf
of ValueType.Nan:
result = false

View File

@ -23,7 +23,7 @@
import segfaults
import types/objecttype
import meta/japlvalue
proc reallocate*(pointr: pointer, oldSize: int, newSize: int): pointer =

View File

@ -16,21 +16,14 @@
## types inherit from this simple structure
import tables
<<<<<<< HEAD
import ../meta/japlvalue
=======
import ../types/objecttype
>>>>>>> upstream/master
type
Chunk* = ref object
## A piece of bytecode.
## Consts represents (TODO newdoc)
## Code represents (TODO newdoc)
## Lines represents (TODO newdoc)
<<<<<<< HEAD
consts*: ValueArray
## Consts represents the constants the code is referring to
## Code represents the bytecode
## Lines represents which lines the corresponding bytecode was one (1 to 1 correspondence)
consts*: seq[Value]
code*: seq[uint8]
lines*: seq[int]
@ -138,9 +131,9 @@ proc bool*(obj: ptr Obj): bool =
proc eq*(a: ptr Obj, b: ptr Obj): bool =
## Compares two objects for equality
if obj.kind != ObjectType.BaseObject:
var newObj = convert obj
result = newObj.eq()
if a.kind != ObjectType.BaseObject:
var newObj = convert(a)
result = newObj.eq(b)
else:
result = a.kind == b.kind
@ -202,8 +195,100 @@ proc binaryXor(self, other: ptr Obj): ptr Obj =
## Returns the result of self ^ other
## or nil if the operation is unsupported
result = nil
=======
consts*: seq[ptr Obj]
code*: seq[uint8]
lines*: seq[int]
>>>>>>> upstream/master
func isNil*(value: Value): bool =
## Returns true if the given value
## is a JAPL nil object
result = value.kind == ValueType.Nil
func isBool*(value: Value): bool =
## Returns true if the given value
## is a JAPL bool
result = value.kind == ValueType.Bool
func isInt*(value: Value): bool =
## Returns true if the given value
## is a JAPL integer
result = value.kind == ValueType.Integer
func isFloat*(value: Value): bool =
## Returns true if the given value
## is a JAPL float
result = value.kind == ValueType.Double
func isInf*(value: Value): bool =
## Returns true if the given value
## is a JAPL inf object
result = value.kind == ValueType.Inf or value.kind == ValueType.Minf
func isNan*(value: Value): bool =
## Returns true if the given value
## is a JAPL nan object
result = value.kind == ValueType.Nan
func isNum*(value: Value): bool =
## Returns true if the given value is
## either a JAPL number, nan or inf
result = isInt(value) or isFloat(value) or isInf(value) or isNan(value)
func isObj*(value: Value): bool =
## Returns if the current value is a JAPL object
result = value.kind == ValueType.Object
func isStr*(value: Value): bool =
## Returns true if the given object is a JAPL string
result = isObj(value) and value.obj.kind == ObjectType.String
func toBool*(value: Value): bool =
## Converts a JAPL bool to a nim bool
result = value.boolValue
func toInt*(value: Value): int =
## Converts a JAPL int to a nim int
result = value.intValue
func toFloat*(value: Value): float =
## Converts a JAPL float to a nim float
result = value.floatValue
func toStr*(value: Value): string =
## Converts a JAPL string into a nim string
var strObj = cast[ptr String](value.obj)
for i in 0..strObj.str.len - 1:
result.add(strObj.str[i])
func asInt*(n: int): Value =
## Creates an int object
result = Value(kind: ValueType.Integer, intValue: n)
func asFloat*(n: float): Value =
## Creates a float object (double)
result = Value(kind: ValueType.Double, floatValue: n)
func asBool*(b: bool): Value =
## Creates a boolean object
result = Value(kind: ValueType.Bool, boolValue: b)
func asValue*(obj: ptr Obj): Value =
## Creates a Value object of ValueType.Object as type and obj (arg 1) as
## contained obj
result = Value(kind: ValueType.Object, obj: obj)

View File

@ -15,14 +15,7 @@
## The module dedicated to the Chunk type
## A chunk is a piece of bytecode.
<<<<<<< HEAD:meta/opcode.nim
<<<<<<< HEAD:meta/chunk.nim
=======
import japlvalue
>>>>>>> 7649cf6e3bdf4ce47c9c63bbdbe3e99a53274a8d:meta/opcode.nim
=======
import ../types/objecttype
>>>>>>> upstream/master:meta/chunk.nim
type
OpCode* {.pure.} = enum
@ -69,19 +62,7 @@ type
Bnot
<<<<<<< HEAD:meta/chunk.nim
Chunk* = ref object
## A piece of bytecode.
## Consts is the chunk's constant table
## Code contains the compiled bytecode
## Lines maps bytecode instructions to lines
consts*: seq[ptr Obj]
code*: seq[uint8]
lines*: seq[int] # TODO: Run-length encoding?
=======
>>>>>>> 7649cf6e3bdf4ce47c9c63bbdbe3e99a53274a8d:meta/opcode.nim
const simpleInstructions* = {OpCode.Return, OpCode.Add, OpCode.Multiply,
OpCode.Divide, OpCode.Subtract,
OpCode.Mod, OpCode.Pow, OpCode.Nil,
@ -123,13 +104,13 @@ proc freeChunk*(self: Chunk) =
self.lines = @[]
proc addConstant*(self: Chunk, constant: ptr Obj): int =
proc addConstant*(self: Chunk, constant: Value): int =
## Adds a constant to a chunk. Returns its index.
self.consts.add(constant)
return self.consts.high() # The index of the constant
proc writeConstant*(self: Chunk, constant: ptr Obj): array[3, uint8] =
proc writeConstant*(self: Chunk, constant: Value): array[3, uint8] =
## Writes a constant to a chunk. Returns its index casted to an array.
## TODO newdoc
let index = self.addConstant(constant)

View File

@ -13,7 +13,7 @@
# limitations under the License.
import tokentype
import valueobject
import japlvalue
# Token object

View File

@ -1,133 +0,0 @@
# 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.
## This module represents the generic interface that JAPL uses internally
## to represent types. Small-sized entities such as numbers and booleans are
## treated differently with respect to bigger and more complex ones such as
## strings and functions. That is because those more comolex entities are
## allocated on the heap, while the simpler ones live on the stack
# import ../types/functiontype
import japlvalue
import ../types/stringtype
import strformat
type
ValueArray* = ref object
values*: seq[Value]
func newValueArray*(): ValueArray =
## Creates a new ValueArray
result = ValueArray(values: @[])
func writeValueArray*(arr: var ValueArray, value: Value) =
## Adds a value to a ValueArray object
arr.values.add(value)
func isNil*(value: Value): bool =
## Returns true if the given value
## is a JAPL nil object
result = value.kind == ValueType.Nil
func isBool*(value: Value): bool =
## Returns true if the given value
## is a JAPL bool
result = value.kind == ValueType.Bool
func isInt*(value: Value): bool =
## Returns true if the given value
## is a JAPL integer
result = value.kind == ValueType.Integer
func isFloat*(value: Value): bool =
## Returns true if the given value
## is a JAPL float
result = value.kind == ValueType.Double
func isInf*(value: Value): bool =
## Returns true if the given value
## is a JAPL inf object
result = value.kind == ValueType.Inf or value.kind == ValueType.Minf
func isNan*(value: Value): bool =
## Returns true if the given value
## is a JAPL nan object
result = value.kind == ValueType.Nan
func isNum*(value: Value): bool =
## Returns true if the given value is
## either a JAPL number, nan or inf
result = isInt(value) or isFloat(value) or isInf(value) or isNan(value)
func isObj*(value: Value): bool =
## Returns if the current value is a JAPL object
result = value.kind == ValueType.Object
func isStr*(value: Value): bool =
## Returns true if the given object is a JAPL string
result = isObj(value) and value.obj.kind == ObjectType.String
func toBool*(value: Value): bool =
## Converts a JAPL bool to a nim bool
result = value.boolValue
func toInt*(value: Value): int =
## Converts a JAPL int to a nim int
result = value.intValue
func toFloat*(value: Value): float =
## Converts a JAPL float to a nim float
result = value.floatValue
func toStr*(value: Value): string =
## Converts a JAPL string into a nim string
var strObj = cast[ptr String](value.obj)
for i in 0..strObj.str.len - 1:
result.add(strObj.str[i])
func asInt*(n: int): Value =
## Creates an int object
result = Value(kind: ValueType.Integer, intValue: n)
func asFloat*(n: float): Value =
## Creates a float object (double)
result = Value(kind: ValueType.Double, floatValue: n)
func asBool*(b: bool): Value =
## Creates a boolean object
result = Value(kind: ValueType.Bool, boolValue: b)
proc asStr*(s: string): Value =
## Creates a string object
result = Value(kind: ValueType.Object, obj: newString(s))

View File

@ -14,8 +14,7 @@
# WIP - Not working
import ../meta/valueobject
import objecttype
import ../meta/japlvalue
import exceptions
import ../memory

View File

@ -19,12 +19,11 @@
# code objects that can be compiled inside the JAPL runtime, pretty much
# like in Python
import objecttype
import stringtype
import strformat
import ../memory
import ../meta/chunk
import ../meta/valueobject
import ../meta/opcode
import ../meta/japlvalue
import tables
@ -43,7 +42,7 @@ proc newFunction*(name: string = "", chunk: Chunk = newChunk(), arity: int = 0):
result.chunk = chunk
proc isFalsey*(fn: Function): bool =
proc isFalsey*(fn: ptr Function): bool =
return false

View File

@ -17,7 +17,7 @@
# therefore immutable from the user's perspective. They are
# natively ASCII encoded, but soon they will support for unicode.
import objecttype
import ../meta/japlvalue
import strformat
import ../memory
@ -65,3 +65,8 @@ proc newString*(str: string): ptr String =
proc typeName*(s: ptr String): string =
return "string"
proc asStr*(s: string): Value =
## Creates a string object
result = Value(kind: ValueType.Object, obj: newString(s))