japl/meta/valueobject.nim

151 lines
4.3 KiB
Nim

# 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 ../types/objecttype
import ../types/stringtype
import strformat
type
ValueType* {.pure.} = enum
# All possible value types (this is the VM's notion of 'type', not the end user's)
Integer, Double, Bool, Nil, Object, Nan, Inf, Minf
Value* = object
## Represents an internal JAPL type
case kind*: ValueType
of ValueType.Integer:
intValue*: int
of ValueType.Double:
floatValue*: float
of ValueType.Bool:
boolValue*: bool
of ValueType.Nil, ValueType.Inf, ValueType.Nan, ValueType.Minf:
discard
of ValueType.Object:
obj*: ptr Obj
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))