japl/src/types/function.nim

94 lines
2.9 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.
import baseObject
import ../meta/opcode
import japlString
import arrayList
type
FunctionType* {.pure.} = enum
## All code in JAPL is compiled
## as if it was inside some sort
## of function. To differentiate
## between actual functions and
## the top-level code, this tiny
## enum is used to tell the two
## contexts apart when compiling
Func, Script, Lambda
Function* = object of Obj
## A function object
name*: ptr String
arity*: int # The number of required parameters
optionals*: int # The number of optional parameters
defaults*: ptr ArrayList[ptr String]
chunk*: Chunk # The function's body
proc newFunction*(name: string = "", chunk: Chunk, arity: int = 0): ptr Function =
## Allocates a new function object with the given
## bytecode chunk and arity. If the name is an empty string
## (the default), the function will be an
## anonymous code object
# TODO: Add support for optional parameters
result = allocateObj(Function, ObjectType.Function)
if name.len >= 1:
result.name = name.asStr()
else:
result.name = nil
result.arity = arity
result.chunk = chunk
result.optionals = 0 # TODO
result.defaults = newArrayList[ptr String]()
proc newLambda*(chunk: Chunk, arity: int = 0): ptr Function =
## Allocates a new lambda object (anonymous function) with the given
## bytecode chunk and arity
# TODO: Add support for optional parameters
result = allocateObj(Function, ObjectType.Function)
result.name = "<lambda function>".asStr()
result.arity = arity
result.chunk = chunk
result.optionals = 0
proc typeName*(self: ptr Function): string =
result = "function"
proc stringify*(self: ptr Function): string =
if self.name != nil:
if self.name.toStr() == "<lambda function>":
result = self.name.toStr()
else:
result = "<function '" & self.name.toStr() & "'>"
else:
result = "<code object>"
proc isFalsey*(self: ptr Function): bool =
result = false
proc hash*(self: ptr Function): uint64 =
# TODO: Hashable?
raise newException(NotImplementedError, "unhashable type 'function'")
proc eq*(self, other: ptr Function): bool =
result = self == other # Pointer equality