Initial work on the type system. Added ImplicitReturn bytecode optimization. Made checkDecl a template instead of a procedure
This commit is contained in:
parent
1afe2f2f47
commit
10df2d3c17
|
@ -11,9 +11,9 @@
|
|||
# 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.
|
||||
|
||||
# Implementation of a custom list data type for JAPL objects (used also internally by the VM)
|
||||
|
||||
{.experimental: "implicitDeref".}
|
||||
import iterable
|
||||
import ../../memory/allocator
|
||||
import baseObject
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
# limitations under the License.
|
||||
|
||||
|
||||
## The base JAPL object
|
||||
|
||||
import ../../memory/allocator
|
||||
|
||||
|
||||
|
@ -28,7 +30,8 @@ type
|
|||
## The base object for all
|
||||
## JAPL types. Every object
|
||||
## in JAPL implicitly inherits
|
||||
## from this base type
|
||||
## from this base type and extends
|
||||
## its functionality
|
||||
kind*: ObjectType
|
||||
hashValue*: uint64
|
||||
|
||||
|
@ -36,7 +39,7 @@ type
|
|||
## Object constructors and allocators
|
||||
|
||||
proc allocateObject*(size: int, kind: ObjectType): ptr Obj =
|
||||
## Wrapper around memory.reallocate to create a new generic JAPL object
|
||||
## Wrapper around reallocate() to create a new generic JAPL object
|
||||
result = cast[ptr Obj](reallocate(nil, 0, size))
|
||||
result.kind = kind
|
||||
|
||||
|
@ -50,13 +53,32 @@ template allocateObj*(kind: untyped, objType: ObjectType): untyped =
|
|||
proc newObj*: ptr Obj =
|
||||
## Allocates a generic JAPL object
|
||||
result = allocateObj(Obj, ObjectType.BaseObject)
|
||||
result.hashValue = 0x123FFFF
|
||||
|
||||
|
||||
proc asObj*(self: ptr Obj): ptr Obj =
|
||||
## Casts a specific JAPL object into a generic
|
||||
## pointer to Obj
|
||||
result = cast[ptr Obj](self)
|
||||
## Default object methods implementations
|
||||
|
||||
# In JAPL code, this method will be called
|
||||
# stringify()
|
||||
proc `$`*(self: ptr Obj): string = "<object>"
|
||||
proc stringify*(self: ptr Obj): string = $self
|
||||
|
||||
proc hash*(self: ptr Obj): uint64 = 0x123FFFF # Constant hash value
|
||||
proc `$`*(self: ptr Obj): string = "<object>"
|
||||
proc hash*(self: ptr Obj): int64 = 0x123FFAA # Constant hash value
|
||||
# I could've used mul, sub and div, but "div" is a reserved
|
||||
# keyword and using `div` looks ugly. So to keep everything
|
||||
# consistent I just made all names long
|
||||
proc multiply*(self, other: ptr Obj): ptr Obj = nil
|
||||
proc sum*(self, other: ptr Obj): ptr Obj = nil
|
||||
proc divide*(self, other: ptr Obj): ptr Obj = nil
|
||||
proc subtract*(self, other: ptr Obj): ptr Obj = nil
|
||||
# Returns 0 if self == other, a negative number if self < other
|
||||
# and a positive number if self > other. This is a convenience
|
||||
# method to implement all basic comparison operators in one
|
||||
# method
|
||||
proc compare*(self, other: ptr Obj): ptr Obj = nil
|
||||
# Specific methods for each comparison
|
||||
proc equalTo*(self, other: ptr Obj): ptr Obj = nil
|
||||
proc greaterThan*(self, other: ptr Obj): ptr Obj = nil
|
||||
proc lessThan*(self, other: ptr Obj): ptr Obj = nil
|
||||
proc greaterOrEqual*(self, other: ptr Obj): ptr Obj = nil
|
||||
proc lessOrEqual*(self, other: ptr Obj): ptr Obj = nil
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright 2022 Mattia Giambirtone & All Contributors
|
||||
#
|
||||
# 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.
|
||||
|
||||
## Implementation of integer types
|
||||
|
||||
import baseObject
|
||||
import lenientops
|
||||
|
||||
|
||||
type Float* = object of Obj
|
||||
value: float64
|
||||
|
||||
|
||||
proc newFloat*(value: float): ptr Float =
|
||||
## Initializes a new JAPL
|
||||
## float object from
|
||||
## a machine native float
|
||||
result = allocateObj(Float, ObjectType.Float)
|
||||
result.value = value
|
||||
|
||||
|
||||
proc toNativeFloat*(self: ptr Float): float =
|
||||
## Returns the float's machine
|
||||
## native underlying value
|
||||
result = self.value
|
||||
|
||||
|
||||
proc `$`*(self: ptr Float): string = $self.value
|
||||
|
||||
|
||||
proc hash*(self: ptr Float): int64 =
|
||||
## Implements hashing
|
||||
## for the given float
|
||||
if self.value - int(self.value) == self.value:
|
||||
result = int(self.value)
|
||||
else:
|
||||
result = 2166136261 xor int(self.value) # TODO: Improve this
|
||||
result *= 16777619
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright 2022 Mattia Giambirtone & All Contributors
|
||||
#
|
||||
# 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.
|
||||
|
||||
## Implementation of integer types
|
||||
|
||||
import baseObject
|
||||
|
||||
|
||||
type Integer* = object of Obj
|
||||
value: int64
|
||||
|
||||
|
||||
proc newInteger*(value: int64): ptr Integer =
|
||||
## Initializes a new JAPL
|
||||
## integer object from
|
||||
## a machine native integer
|
||||
result = allocateObj(Integer, ObjectType.Integer)
|
||||
result.value = value
|
||||
|
||||
|
||||
proc toNativeInteger*(self: ptr Integer): int64 =
|
||||
## Returns the integer's machine
|
||||
## native underlying value
|
||||
result = self.value
|
||||
|
||||
|
||||
proc `$`*(self: ptr Integer): string = $self.value
|
||||
proc hash*(self: ptr Integer): int64 = self.value
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# Copyright 2022 Mattia Giambirtone & All Contributors
|
||||
#
|
||||
# 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.
|
||||
|
||||
# JAPL string implementations
|
|
@ -977,7 +977,7 @@ proc funDecl(self: Compiler, node: FunDecl) =
|
|||
if not self.enableOptimizations:
|
||||
self.emitBytes(OpCode.Nil, OpCode.Return)
|
||||
else:
|
||||
self.emitBytes(ImplicitReturn)
|
||||
self.emitByte(ImplicitReturn)
|
||||
|
||||
# Currently defer is not functional so we
|
||||
# just pop the instructions
|
||||
|
|
|
@ -765,7 +765,8 @@ proc forStmt(self: Parser): ASTNode =
|
|||
# increment variable which doesn't really make sense, but still
|
||||
# allow people that like verbosity (for *some* reason) to use
|
||||
# private static var declarations as well as just private var
|
||||
# and static var
|
||||
# and static var as well as providing decently specific error
|
||||
# messages
|
||||
if self.match(Semicolon):
|
||||
discard
|
||||
elif self.match(Dynamic):
|
||||
|
@ -839,7 +840,7 @@ proc ifStmt(self: Parser): ASTNode =
|
|||
result = newIfStmt(condition, thenBranch, elseBranch, tok)
|
||||
|
||||
|
||||
proc checkDecl(self: Parser, isStatic, isPrivate: bool) =
|
||||
template checkDecl(self: Parser, isStatic, isPrivate: bool) =
|
||||
## Handy utility function that avoids us from copy
|
||||
## pasting the same checks to all declaration handlers
|
||||
if not isStatic and self.currentFunction != nil:
|
||||
|
|
Loading…
Reference in New Issue