Added missing files
This commit is contained in:
parent
9567319c40
commit
b589f8109a
|
@ -0,0 +1,219 @@
|
||||||
|
## A simple, dynamically-growing stack implementation
|
||||||
|
|
||||||
|
import strformat
|
||||||
|
import ../config
|
||||||
|
|
||||||
|
|
||||||
|
type Stack*[T] = object
|
||||||
|
## A stack for use in the
|
||||||
|
## peon runtime environment
|
||||||
|
container: ptr UncheckedArray[T]
|
||||||
|
capacity*: int
|
||||||
|
length: int
|
||||||
|
|
||||||
|
|
||||||
|
proc newStack*[T]: ptr Stack[T] =
|
||||||
|
## Allocates a new, empty stack
|
||||||
|
## with a starting capacity of 8
|
||||||
|
result = cast[ptr Stack[T]](alloc(sizeof(Stack)))
|
||||||
|
result.capacity = 8
|
||||||
|
result.container = cast[ptr UncheckedArray[T]](alloc(sizeof(T) * 8))
|
||||||
|
result.length = 0
|
||||||
|
|
||||||
|
|
||||||
|
proc push*[T](self: ptr Stack[T], elem: T) =
|
||||||
|
## Pushes an object onto the stack
|
||||||
|
if self.capacity <= self.length:
|
||||||
|
self.capacity *= HeapGrowFactor
|
||||||
|
self.container = cast[ptr UncheckedArray[T]](realloc(self.container, self.capacity))
|
||||||
|
self.container[self.length] = elem
|
||||||
|
self.length += 1
|
||||||
|
|
||||||
|
|
||||||
|
proc pop*[T](self: ptr Stack[T], idx: int = -1): T =
|
||||||
|
## Pops an item off the stack. By default, the last
|
||||||
|
## element is popped, in which case the operation's
|
||||||
|
## time complexity is O(1). When an arbitrary element
|
||||||
|
## is popped, the complexity rises to O(k) where k
|
||||||
|
## is the number of elements that had to be shifted
|
||||||
|
## by 1 to avoid empty slots
|
||||||
|
var idx = idx
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, "pop from empty Stack")
|
||||||
|
if idx == -1:
|
||||||
|
idx = self.length - 1
|
||||||
|
if idx notin 0..self.length - 1:
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: {idx} notin 0..{self.length - 1}")
|
||||||
|
result = self.container[idx]
|
||||||
|
if idx != self.length - 1:
|
||||||
|
for i in countup(idx, self.length - 1):
|
||||||
|
self.container[i] = self.container[i + 1]
|
||||||
|
self.capacity -= 1
|
||||||
|
self.length -= 1
|
||||||
|
|
||||||
|
|
||||||
|
proc pop*[T](self: ptr Stack[T], idx: uint64): T =
|
||||||
|
## Pops an item off the stack
|
||||||
|
var idx = idx
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, "pop from empty Stack")
|
||||||
|
if idx notin 0'u64..uint64(self.length - 1):
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: {idx} notin 0..{self.length - 1}")
|
||||||
|
result = self.container[idx]
|
||||||
|
if idx != uint64(self.length - 1):
|
||||||
|
for i in countup(idx, uint64(self.length - 1)):
|
||||||
|
self.container[i] = self.container[i + 1]
|
||||||
|
self.capacity -= 1
|
||||||
|
self.length -= 1
|
||||||
|
|
||||||
|
|
||||||
|
proc `[]`*[T](self: ptr Stack[T], idx: int): T =
|
||||||
|
## Retrieves an item from the stack, in constant
|
||||||
|
## time
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: : {idx} notin 0..{self.length - 1}")
|
||||||
|
if idx notin 0..self.length - 1:
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: {idx} notin 0..{self.length - 1}")
|
||||||
|
result = self.container[idx]
|
||||||
|
|
||||||
|
|
||||||
|
proc `[]`*[T](self: ptr Stack[T], idx: uint64): T =
|
||||||
|
## Retrieves an item from the stack, in constant
|
||||||
|
## time
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: : {idx} notin 0..{self.length - 1}")
|
||||||
|
if idx notin 0'u64..uint64(self.length - 1):
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: {idx} notin 0..{self.length - 1}")
|
||||||
|
result = self.container[idx]
|
||||||
|
|
||||||
|
|
||||||
|
proc `[]`*[T](self: ptr Stack[T], idx: BackwardsIndex): T =
|
||||||
|
## Retrieves an item from the stack, in constant
|
||||||
|
## time
|
||||||
|
result = self[self.len() - int(idx)]
|
||||||
|
|
||||||
|
|
||||||
|
proc `[]`*[T](self: ptr Stack[T], slice: Hslice[int, int]): ptr Stack[T] =
|
||||||
|
## Retrieves a subset of the stack, in O(k) time where k is the size
|
||||||
|
## of the slice
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, "Stack index out of bounds")
|
||||||
|
if slice.a notin 0..self.length - 1 or slice.b notin 0..self.length:
|
||||||
|
raise newException(IndexDefect, "Stack index out of bounds")
|
||||||
|
result = newStack()
|
||||||
|
for i in countup(slice.a, slice.b - 1):
|
||||||
|
result.push(self.container[i])
|
||||||
|
|
||||||
|
|
||||||
|
proc `[]=`*[T](self: ptr Stack[T], idx: int, obj: T) =
|
||||||
|
## Assigns an object to the given index, in constant
|
||||||
|
## time
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, "Stack is empty")
|
||||||
|
if idx notin 0..self.length - 1:
|
||||||
|
raise newException(IndexDefect, "Stack index out of bounds")
|
||||||
|
self.container[idx] = obj
|
||||||
|
|
||||||
|
|
||||||
|
proc `[]=`*[T](self: ptr Stack[T], idx: uint64, obj: T) =
|
||||||
|
## Assigns an object to the given index, in constant
|
||||||
|
## time
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, "Stack is empty")
|
||||||
|
if idx notin 0'u64..uint64(self.length - 1):
|
||||||
|
raise newException(IndexDefect, "Stack index out of bounds")
|
||||||
|
self.container[idx] = obj
|
||||||
|
|
||||||
|
|
||||||
|
proc delete*[T](self: ptr Stack[T], idx: int) =
|
||||||
|
## Deletes an object from the given index.
|
||||||
|
## uint64his method shares the time complexity
|
||||||
|
## of self.pop()
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, "delete from empty Stack")
|
||||||
|
if idx notin 0..self.length - 1:
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: {idx} notin 0..{self.length - 1}")
|
||||||
|
discard self.pop(idx)
|
||||||
|
|
||||||
|
|
||||||
|
proc delete*[T](self: ptr Stack[T], idx: uint64) =
|
||||||
|
## Deletes an object from the given index.
|
||||||
|
## uint64his method shares the time complexity
|
||||||
|
## of self.pop()
|
||||||
|
if self.length == 0:
|
||||||
|
raise newException(IndexDefect, "delete from empty Stack")
|
||||||
|
if idx notin 0'u64..uint64(self.length - 1):
|
||||||
|
raise newException(IndexDefect, &"Stack index out of bounds: {idx} notin 0..{self.length - 1}")
|
||||||
|
discard self.pop(idx)
|
||||||
|
|
||||||
|
|
||||||
|
proc contains*[T](self: ptr Stack[T], elem: T): bool =
|
||||||
|
## Returns true if the given object is present
|
||||||
|
## in the list, false otherwise. O(n) complexity
|
||||||
|
if self.length > 0:
|
||||||
|
for i in 0..self.length - 1:
|
||||||
|
if self[i] == elem:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
proc high*[T](self: ptr Stack[T]): int =
|
||||||
|
## Returns the index of the last
|
||||||
|
## element in the list, in constant time
|
||||||
|
result = self.length - 1
|
||||||
|
|
||||||
|
|
||||||
|
proc len*[T](self: ptr Stack[T]): int =
|
||||||
|
## Returns the length of the list
|
||||||
|
## in constant time
|
||||||
|
result = self.length
|
||||||
|
|
||||||
|
|
||||||
|
iterator pairs*[T](self: ptr Stack[T]): tuple[key: int, val: T] =
|
||||||
|
## Implements pairwise iteration (similar to python's enumerate)
|
||||||
|
for i in countup(0, self.length - 1):
|
||||||
|
yield (key: i, val: self[i])
|
||||||
|
|
||||||
|
|
||||||
|
iterator items*[T](self: ptr Stack[T]): T =
|
||||||
|
## Implements iteration
|
||||||
|
for i in countup(0, self.length - 1):
|
||||||
|
yield self[i]
|
||||||
|
|
||||||
|
|
||||||
|
proc reversed*[T](self: ptr Stack[T], first: int = -1, last: int = 0): ptr Stack[T] =
|
||||||
|
## Returns a reversed version of the given stack, from first to last.
|
||||||
|
## First defaults to -1 (the end of the list) and last defaults to 0 (the
|
||||||
|
## beginning of the list)
|
||||||
|
var first = first
|
||||||
|
if first == -1:
|
||||||
|
first = self.length - 1
|
||||||
|
result = newStack()
|
||||||
|
for i in countdown(first, last):
|
||||||
|
result.push(self[i])
|
||||||
|
|
||||||
|
|
||||||
|
proc extend*[T](self: ptr Stack[T], other: seq[T]) =
|
||||||
|
## Iteratively calls self.push() with the elements
|
||||||
|
## from a nim sequence
|
||||||
|
for elem in other:
|
||||||
|
self.push(elem)
|
||||||
|
|
||||||
|
|
||||||
|
proc extend*[T](self: ptr Stack[T], other: ptr Stack[T]) =
|
||||||
|
## Iteratively calls self.push() with the elements
|
||||||
|
## from another Stack
|
||||||
|
for elem in other:
|
||||||
|
self.push(elem)
|
||||||
|
|
||||||
|
|
||||||
|
proc `$`*[T](self: ptr Stack[T]): string =
|
||||||
|
## Returns a string representation
|
||||||
|
## of self
|
||||||
|
result = "["
|
||||||
|
if self.length > 0:
|
||||||
|
for i in 0..self.length - 1:
|
||||||
|
result = result & $self.container[i]
|
||||||
|
if i < self.length - 1:
|
||||||
|
result = result & ", "
|
||||||
|
result = result & "]"
|
|
@ -0,0 +1,17 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
## The peon garbage collector and memory manager
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
## Peon's math module
|
||||||
|
import std;
|
||||||
|
|
||||||
|
|
||||||
|
const pi* = 3.141592653589793;
|
||||||
|
const e* = 2.718281828459045;
|
||||||
|
const tau* = 6.283185307179586;
|
||||||
|
|
||||||
|
|
||||||
|
fn abs*[T: int64 | int32 | int16 | int8](n: T): T {
|
||||||
|
## Returns the absolute value of the given number
|
||||||
|
if n < 0 {
|
||||||
|
return -n;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
## Utilities to print formatted error messages to stderr
|
||||||
|
import ../frontend/compiler
|
||||||
|
import ../frontend/parser
|
||||||
|
import ../frontend/lexer
|
||||||
|
import ../util/serializer
|
||||||
|
|
||||||
|
|
||||||
|
import std/os
|
||||||
|
import std/terminal
|
||||||
|
import std/strutils
|
||||||
|
import std/strformat
|
||||||
|
|
||||||
|
|
||||||
|
proc print*(exc: CompileError) =
|
||||||
|
## Prints a formatted error message
|
||||||
|
## for compilation errors to stderr
|
||||||
|
var file = exc.file
|
||||||
|
if file notin ["<string>", ""]:
|
||||||
|
file = relativePath(exc.file, getCurrentDir())
|
||||||
|
let line = exc.compiler.getSource().splitLines()[exc.line - 1].strip(chars={'\n'})
|
||||||
|
let fn = exc.compiler.getCurrentFunction()
|
||||||
|
let node = exc.node
|
||||||
|
let pos = node.getRelativeBoundaries()
|
||||||
|
stderr.styledWrite(fgRed, styleBright, "Error in ", fgYellow, &"{file}:{exc.line}:{pos.start}")
|
||||||
|
if not fn.isNil() and fn.kind == funDecl:
|
||||||
|
stderr.styledWrite(fgRed, styleBright, " in function ", fgYellow, FunDecl(fn).name.token.lexeme)
|
||||||
|
stderr.styledWriteLine(styleBright, fgDefault, ": ", exc.msg)
|
||||||
|
stderr.styledWrite(fgRed, styleBright, "Source line: ", resetStyle, fgDefault, line[0..<pos.start])
|
||||||
|
stderr.styledWrite(fgRed, styleUnderscore, line[pos.start..pos.stop])
|
||||||
|
stderr.styledWriteLine(fgDefault, line[pos.stop + 1..^1])
|
||||||
|
|
||||||
|
|
||||||
|
proc print*(exc: ParseError) =
|
||||||
|
## Prints a formatted error message
|
||||||
|
## for parsing errors to stderr
|
||||||
|
var file = exc.file
|
||||||
|
if file notin ["<string>", ""]:
|
||||||
|
file = relativePath(exc.file, getCurrentDir())
|
||||||
|
let line = exc.parser.getSource().splitLines()[exc.line - 1].strip(chars={'\n'})
|
||||||
|
let pos = exc.token.relPos
|
||||||
|
stderr.styledWriteLine(fgRed, styleBright, "Error in ", fgYellow, &"{file}:{exc.line}:{pos.start}", fgDefault, ": " & exc.msg)
|
||||||
|
stderr.styledWrite(fgRed, styleBright, "Source line: ", resetStyle, fgDefault, line[0..<pos.start])
|
||||||
|
stderr.styledWrite(fgRed, styleUnderscore, line[pos.start..pos.stop])
|
||||||
|
stderr.styledWriteLine(fgDefault, line[pos.stop + 1..^1])
|
||||||
|
|
||||||
|
|
||||||
|
proc print*(exc: LexingError) =
|
||||||
|
## Prints a formatted error message
|
||||||
|
## for lexing errors to stderr
|
||||||
|
var file = exc.file
|
||||||
|
if file notin ["<string>", ""]:
|
||||||
|
file = relativePath(exc.file, getCurrentDir())
|
||||||
|
let line = exc.lexer.getSource().splitLines()[exc.line - 1].strip(chars={'\n'})
|
||||||
|
let pos = exc.pos
|
||||||
|
stderr.styledWriteLine(fgRed, styleBright, "Error in ", fgYellow, &"{file}:{exc.line}:{pos.start}", fgDefault, ": " & exc.msg)
|
||||||
|
stderr.styledWrite(fgRed, styleBright, "Source line: ", resetStyle, fgDefault, line[0..<pos.start])
|
||||||
|
stderr.styledWrite(fgRed, styleUnderscore, line[pos.start..<pos.stop])
|
||||||
|
stderr.styledWriteLine(fgDefault, line[pos.stop..^1])
|
||||||
|
|
||||||
|
|
||||||
|
proc print*(exc: SerializationError) =
|
||||||
|
## Prints a formatted error message
|
||||||
|
## for serialization errors to stderr
|
||||||
|
var file = exc.file
|
||||||
|
if file notin ["<string>", ""]:
|
||||||
|
file = relativePath(exc.file, getCurrentDir())
|
||||||
|
stderr.styledWriteLine(fgRed, styleBright, "Error while (de-)serializing ", fgYellow, file, fgDefault, &": {exc.msg}")
|
||||||
|
|
||||||
|
|
||||||
|
proc print*(exc: IOError, file: string) =
|
||||||
|
## Prints a formatted error message
|
||||||
|
## for nim I/O errors to stderr
|
||||||
|
var file = file
|
||||||
|
if file notin ["<string>", ""]:
|
||||||
|
file = relativePath(file, getCurrentDir())
|
||||||
|
stderr.styledWriteLine(fgRed, styleBright, "Error while trying to read ", fgYellow, file, fgDefault, &": {exc.msg}")
|
||||||
|
|
||||||
|
|
||||||
|
proc print*(exc: OSError, file: string, errno: OSErrorCode) =
|
||||||
|
## Prints a formatted error message
|
||||||
|
## for nim OS errors to stderr
|
||||||
|
var file = file
|
||||||
|
if file notin ["<string>", ""]:
|
||||||
|
file = relativePath(file, getCurrentDir())
|
||||||
|
stderr.styledWriteLine(fgRed, styleBright, "Error while trying to read ", fgYellow, file, fgDefault, &": {exc.msg} ({osErrorMsg(errno)})",
|
||||||
|
fgRed, "[errno ", fgYellow, $errno, fgRed, "]")
|
|
@ -0,0 +1,12 @@
|
||||||
|
import std;
|
||||||
|
|
||||||
|
|
||||||
|
var a = 5;
|
||||||
|
fn f {
|
||||||
|
a = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print(a);
|
||||||
|
f();
|
||||||
|
#print(a);
|
|
@ -0,0 +1,6 @@
|
||||||
|
import std;
|
||||||
|
import math;
|
||||||
|
|
||||||
|
|
||||||
|
print("Testing math module");
|
||||||
|
print(math.abs(-5) == 5);
|
Loading…
Reference in New Issue