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