Initial work on call resolution, added support for running files
This commit is contained in:
parent
6d6ae3ee7a
commit
42ab1d4c6e
|
@ -23,6 +23,7 @@ import algorithm
|
|||
import parseutils
|
||||
import strutils
|
||||
import sequtils
|
||||
import os
|
||||
|
||||
|
||||
export ast
|
||||
|
@ -43,9 +44,11 @@ type
|
|||
node*: ASTNode
|
||||
case kind*: TypeKind:
|
||||
of Function:
|
||||
args*: seq[tuple[name: IdentExpr, kind: Type]]
|
||||
returnType*: Type
|
||||
else:
|
||||
discard
|
||||
|
||||
# This way we don't have recursive dependency issues
|
||||
import meta/bytecode
|
||||
export bytecode
|
||||
|
@ -158,6 +161,8 @@ proc identifier(self: Compiler, node: IdentExpr)
|
|||
proc varDecl(self: Compiler, node: VarDecl)
|
||||
proc inferType(self: Compiler, node: LiteralExpr): Type
|
||||
proc inferType(self: Compiler, node: Expression): Type
|
||||
proc findByName(self: Compiler, name: string): seq[Name]
|
||||
proc findByType(self: Compiler, name: string, kind: Type): seq[Name]
|
||||
## End of forward declarations
|
||||
|
||||
## Public getter for nicer error formatting
|
||||
|
@ -190,7 +195,7 @@ proc done(self: Compiler): bool =
|
|||
|
||||
proc error(self: Compiler, message: string) {.raises: [CompileError].} =
|
||||
## Raises a CompileError exception
|
||||
raise newException(CompileError, message)
|
||||
raise CompileError(msg: message, node: self.getCurrentNode(), file: self.file, module: self.currentModule)
|
||||
|
||||
|
||||
proc step(self: Compiler): ASTNode =
|
||||
|
@ -201,7 +206,7 @@ proc step(self: Compiler): ASTNode =
|
|||
self.current += 1
|
||||
|
||||
|
||||
proc emitByte(self: Compiler, byt: OpCode|uint8) =
|
||||
proc emitByte(self: Compiler, byt: OpCode | uint8) =
|
||||
## Emits a single byte, writing it to
|
||||
## the current chunk being compiled
|
||||
when DEBUG_TRACE_COMPILER:
|
||||
|
@ -209,23 +214,8 @@ proc emitByte(self: Compiler, byt: OpCode|uint8) =
|
|||
self.chunk.write(uint8 byt, self.peek().token.line)
|
||||
|
||||
|
||||
proc emitBytes(self: Compiler, byt1: OpCode|uint8, byt2: OpCode|uint8) =
|
||||
## Emits multiple bytes instead of a single one. This is useful
|
||||
## to emit operators along with their operands or for multi-byte
|
||||
## instructions that are longer than one byte
|
||||
self.emitByte(uint8 byt1)
|
||||
self.emitByte(uint8 byt2)
|
||||
|
||||
|
||||
proc emitBytes(self: Compiler, bytarr: array[2, uint8]) =
|
||||
## Handy helper method to write an array of 2 bytes into
|
||||
## the current chunk, calling emitByte on each of its
|
||||
## elements
|
||||
self.emitBytes(bytarr[0], bytarr[1])
|
||||
|
||||
|
||||
proc emitBytes(self: Compiler, bytarr: openarray[uint8]) =
|
||||
## Handy helper method to write an array of 3 bytes into
|
||||
proc emitBytes(self: Compiler, bytarr: openarray[OpCode | uint8]) =
|
||||
## Handy helper method to write arbitrary bytes into
|
||||
## the current chunk, calling emitByte on each of its
|
||||
## elements
|
||||
for b in bytarr:
|
||||
|
@ -390,6 +380,30 @@ proc detectClosureVariable(self: Compiler, name: IdentExpr,
|
|||
self.chunk.code[entry.codePos + 2] = idx[1]
|
||||
self.chunk.code[entry.codePos + 3] = idx[2]
|
||||
|
||||
proc compareTypes(self: Compiler, a, b: Type): bool
|
||||
|
||||
proc compareTypesWithNullNode(self: Compiler, a, b: Type): bool =
|
||||
## Compares two types without using information from
|
||||
## AST nodes
|
||||
if a == nil:
|
||||
return b == nil
|
||||
elif b == nil:
|
||||
return a == nil
|
||||
if a.kind != b.kind:
|
||||
return false
|
||||
case a.kind:
|
||||
of Function:
|
||||
if a.args.len() != b.args.len():
|
||||
return false
|
||||
elif not self.compareTypes(a.returnType, b.returnType):
|
||||
return false
|
||||
for (argA, argB) in zip(a.args, b.args):
|
||||
if not self.compareTypes(argA.kind, argB.kind):
|
||||
return false
|
||||
return true
|
||||
else:
|
||||
discard
|
||||
|
||||
|
||||
proc compareTypes(self: Compiler, a, b: Type): bool =
|
||||
## Compares two type objects
|
||||
|
@ -406,6 +420,8 @@ proc compareTypes(self: Compiler, a, b: Type): bool =
|
|||
Char, Byte, String, Nil, Nan, Bool, Inf:
|
||||
return true
|
||||
of Function:
|
||||
if a.node == nil or b.node == nil:
|
||||
return self.compareTypesWithNullNode(a, b)
|
||||
let
|
||||
a = FunDecl(a.node)
|
||||
b = FunDecl(b.node)
|
||||
|
@ -413,8 +429,7 @@ proc compareTypes(self: Compiler, a, b: Type): bool =
|
|||
return false
|
||||
elif a.arguments.len() != b.arguments.len():
|
||||
return false
|
||||
elif not self.compareTypes(self.inferType(a.returnType),
|
||||
self.inferType(b.returnType)):
|
||||
elif not self.compareTypes(self.inferType(a.returnType), self.inferType(b.returnType)):
|
||||
return false
|
||||
for (argA, argB) in zip(a.arguments, b.arguments):
|
||||
if argA.mutable != argB.mutable:
|
||||
|
@ -423,8 +438,7 @@ proc compareTypes(self: Compiler, a, b: Type): bool =
|
|||
return false
|
||||
elif argA.isPtr != argB.isPtr:
|
||||
return false
|
||||
elif not self.compareTypes(self.inferType(argA.valueType),
|
||||
self.inferType(argB.valueType)):
|
||||
elif not self.compareTypes(self.inferType(argA.valueType), self.inferType(argB.valueType)):
|
||||
return false
|
||||
return true
|
||||
else:
|
||||
|
@ -702,7 +716,10 @@ proc unary(self: Compiler, node: UnaryExpr) =
|
|||
## Compiles unary expressions such as decimal
|
||||
## and bitwise negation
|
||||
self.expression(node.a) # Pushes the operand onto the stack
|
||||
|
||||
let valueType = self.inferType(node.a)
|
||||
let impl = self.findByType(node.token.lexeme, Type(kind: Function, returnType: valueType, node: nil))
|
||||
if impl.len() == 0:
|
||||
self.error(&"cannot find a suitable implementation for '{node.token.lexeme}'")
|
||||
|
||||
|
||||
proc binary(self: Compiler, node: BinaryExpr) =
|
||||
|
@ -772,10 +789,12 @@ proc declareName(self: Compiler, node: Declaration) =
|
|||
owner: self.currentModule,
|
||||
valueType: Type(kind: Function, node: node,
|
||||
returnType: self.inferType(
|
||||
node.returnType)),
|
||||
node.returnType),
|
||||
args: @[]),
|
||||
codePos: self.chunk.code.len(),
|
||||
name: node.name,
|
||||
isLet: false))
|
||||
let fn = self.names[^1]
|
||||
for argument in node.arguments:
|
||||
if self.names.high() > 16777215:
|
||||
self.error("cannot declare more than 16777216 variables at a time")
|
||||
|
@ -789,6 +808,7 @@ proc declareName(self: Compiler, node: Declaration) =
|
|||
isLet: false))
|
||||
self.names[^1].valueType = self.inferType(argument.valueType)
|
||||
self.names[^1].valueType.node = argument.name
|
||||
fn.valueType.args.add((node.name, self.names[^1].valueType))
|
||||
self.emitByte(LoadVar)
|
||||
self.emitBytes(self.names.high().toTriple())
|
||||
else:
|
||||
|
@ -1274,7 +1294,7 @@ proc compile*(self: Compiler, ast: seq[Declaration], file: string): Chunk =
|
|||
self.names = @[]
|
||||
self.scopeDepth = 0
|
||||
self.currentFunction = nil
|
||||
self.currentModule = self.file
|
||||
self.currentModule = self.file.extractFilename()
|
||||
self.current = 0
|
||||
while not self.done():
|
||||
self.declaration(Declaration(self.step()))
|
||||
|
|
|
@ -19,7 +19,6 @@ import strutils
|
|||
import parseutils
|
||||
import strformat
|
||||
import tables
|
||||
import terminal
|
||||
|
||||
|
||||
import meta/token
|
||||
|
@ -203,7 +202,7 @@ proc step(self: Lexer, n: int = 1): string =
|
|||
inc(self.current)
|
||||
|
||||
|
||||
proc peek*(self: Lexer, distance: int = 0, length: int = 1): string =
|
||||
proc peek(self: Lexer, distance: int = 0, length: int = 1): string =
|
||||
## Returns a stream of characters of
|
||||
## at most length bytes from the source
|
||||
## file, starting at the given distance,
|
||||
|
@ -226,7 +225,7 @@ proc peek*(self: Lexer, distance: int = 0, length: int = 1): string =
|
|||
proc error(self: Lexer, message: string) =
|
||||
## Raises a lexing error with a formatted
|
||||
## error message
|
||||
raise newException(LexingError, message)
|
||||
raise LexingError(msg: message, line: self.line, file: self.file, lexeme: self.peek())
|
||||
|
||||
|
||||
proc check(self: Lexer, s: string, distance: int = 0): bool =
|
||||
|
|
|
@ -11,12 +11,24 @@
|
|||
# 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 token
|
||||
import ast
|
||||
|
||||
|
||||
type
|
||||
## Nim exceptions for internal Peon failures
|
||||
PeonException* = object of CatchableError
|
||||
LexingError* = object of PeonException
|
||||
ParseError* = object of PeonException
|
||||
CompileError* = object of PeonException
|
||||
SerializationError* = object of PeonException
|
||||
PeonException* = ref object of CatchableError
|
||||
LexingError* = ref object of PeonException
|
||||
file*: string
|
||||
lexeme*: string
|
||||
line*: int
|
||||
ParseError* = ref object of PeonException
|
||||
file*: string
|
||||
token*: Token
|
||||
module*: string
|
||||
CompileError* = ref object of PeonException
|
||||
node*: ASTNode
|
||||
file*: string
|
||||
module*: string
|
||||
SerializationError* = ref object of PeonException
|
||||
file*: string
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import strformat
|
||||
import strutils
|
||||
import tables
|
||||
import os
|
||||
|
||||
import meta/token
|
||||
import meta/ast
|
||||
|
@ -152,6 +153,7 @@ proc getCurrentToken*(self: Parser): Token {.inline.} = (if self.getCurrent() >=
|
|||
self.getCurrent() - 1 < 0: self.tokens[^1] else: self.tokens[self.current - 1])
|
||||
proc getCurrentFunction*(self: Parser): Declaration {.inline.} = self.currentFunction
|
||||
proc getFile*(self: Parser): string {.inline.} = self.file
|
||||
proc getModule*(self: Parser): string {.inline.} = self.getFile().extractFilename()
|
||||
|
||||
# Handy templates to make our life easier, thanks nim!
|
||||
template endOfFile: Token = Token(kind: EndOfFile, lexeme: "", line: -1)
|
||||
|
@ -192,7 +194,7 @@ proc step(self: Parser, n: int = 1): Token =
|
|||
|
||||
proc error(self: Parser, message: string) {.raises: [ParseError].} =
|
||||
## Raises a ParseError exception
|
||||
raise newException(ParseError, message)
|
||||
raise ParseError(msg: message, token: self.getCurrentToken(), file: self.file, module: self.getModule())
|
||||
|
||||
|
||||
# Why do we allow strings or enum members of TokenType? Well, it's simple:
|
||||
|
|
104
src/main.nim
104
src/main.nim
|
@ -2,6 +2,7 @@
|
|||
import strformat
|
||||
import strutils
|
||||
import terminal
|
||||
import os
|
||||
# Thanks art <3
|
||||
import jale/editor as ed
|
||||
import jale/templates
|
||||
|
@ -18,7 +19,6 @@ import frontend/compiler as c
|
|||
import backend/vm as v
|
||||
import util/serializer as s
|
||||
|
||||
|
||||
# Forward declarations
|
||||
proc fillSymbolTable(tokenizer: Lexer)
|
||||
proc getLineEditor: LineEditor
|
||||
|
@ -38,8 +38,8 @@ when debugCompiler:
|
|||
import util/debugger
|
||||
|
||||
|
||||
when isMainModule:
|
||||
setControlCHook(proc () {.noconv.} = quit(0))
|
||||
proc repl =
|
||||
styledEcho fgMagenta, "Welcome into the peon REPL!"
|
||||
var
|
||||
keep = true
|
||||
tokens: seq[Token] = @[]
|
||||
|
@ -121,50 +121,116 @@ when isMainModule:
|
|||
when debugRuntime:
|
||||
styledEcho fgCyan, "\n\nExecution step: "
|
||||
vm.run(serialized.chunk)
|
||||
# TODO: The code for error reporting completely
|
||||
# breaks down with multiline input, fix it
|
||||
except LexingError:
|
||||
let lineNo = tokenizer.getLine()
|
||||
let relPos = tokenizer.getRelPos(lineNo)
|
||||
let line = tokenizer.getSource().splitLines()[lineNo - 1].strip()
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while parsing ", fgYellow, &"'{tokenizer.getFile()}'", fgRed, ", module ",
|
||||
fgYellow, &"'{tokenizer.getFile()}'", fgRed, ", line ", fgYellow, $lineNo, fgRed, " at ", fgYellow, &"'{tokenizer.peek()}'",
|
||||
let exc = LexingError(getCurrentException())
|
||||
let relPos = tokenizer.getRelPos(exc.line)
|
||||
let line = tokenizer.getSource().splitLines()[exc.line - 1].strip()
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while parsing ", fgYellow, &"'{exc.file}'", fgRed, ", module ",
|
||||
fgYellow, &"'{exc.file.extractFilename()}'", fgRed, ", line ", fgYellow, $exc.line, fgRed, " at ", fgYellow, &"'{exc.lexeme}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
styledEcho fgBlue, "Source line: " , fgDefault, line
|
||||
styledEcho fgCyan, " ".repeat(len("Source line: ")) & "^".repeat(relPos.stop - relPos.start)
|
||||
except ParseError:
|
||||
let lexeme = parser.getCurrentToken().lexeme
|
||||
let lineNo = parser.getCurrentToken().line
|
||||
let exc = ParseError(getCurrentException())
|
||||
let lexeme = exc.token.lexeme
|
||||
let lineNo = exc.token.line
|
||||
let relPos = tokenizer.getRelPos(lineNo)
|
||||
let fn = parser.getCurrentFunction()
|
||||
let line = tokenizer.getSource().splitLines()[lineNo - 1].strip()
|
||||
var fnMsg = ""
|
||||
if fn != nil and fn.kind == funDecl:
|
||||
fnMsg &= &"in function '{FunDecl(fn).name.token.lexeme}'"
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while parsing ", fgYellow, &"'{parser.getFile()}'", fgRed, ", module ",
|
||||
fgYellow, &"'{parser.getFile()}'", fgRed, ", line ", fgYellow, $lineNo, fgRed, " at ", fgYellow, &"'{lexeme}'",
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while parsing ", fgYellow, &"'{exc.file}'", fgRed, ", module ",
|
||||
fgYellow, &"'{exc.file}'", fgRed, ", line ", fgYellow, $lineNo, fgRed, " at ", fgYellow, &"'{lexeme}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
styledEcho fgBlue, "Source line: " , fgDefault, line
|
||||
styledEcho fgCyan, " ".repeat(len("Source line: ")) & "^".repeat(relPos.stop - relPos.start)
|
||||
except CompileError:
|
||||
let lexeme = compiler.getCurrentNode().token.lexeme
|
||||
let lineNo = compiler.getCurrentNode().token.line
|
||||
let exc = CompileError(getCurrentException())
|
||||
let lexeme = exc.node.token.lexeme
|
||||
let lineNo = exc.node.token.line
|
||||
let relPos = tokenizer.getRelPos(lineNo)
|
||||
let line = tokenizer.getSource().splitLines()[lineNo - 1].strip()
|
||||
var fn = compiler.getCurrentFunction()
|
||||
var fnMsg = ""
|
||||
if fn != nil and fn.kind == funDecl:
|
||||
fnMsg &= &"in function '{FunDecl(fn).name.token.lexeme}'"
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while compiling ", fgYellow, &"'{compiler.getFile()}'", fgRed, ", module ",
|
||||
fgYellow, &"'{compiler.getModule()}'", fgRed, ", line ", fgYellow, $lineNo, fgRed, " at ", fgYellow, &"'{lexeme}'",
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while compiling ", fgYellow, &"'{exc.file}'", fgRed, ", module ",
|
||||
fgYellow, &"'{exc.module}'", fgRed, ", line ", fgYellow, $lineNo, fgRed, " at ", fgYellow, &"'{lexeme}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
styledEcho fgBlue, "Source line: " , fgDefault, line
|
||||
styledEcho fgCyan, " ".repeat(len("Source line: ")) & "^".repeat(relPos.stop - relPos.start)
|
||||
except SerializationError:
|
||||
stderr.styledWriteLine(fgRed, getCurrentExceptionMsg())
|
||||
let exc = SerializationError(getCurrentException())
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while (de-)serializing", fgYellow, &"'{exc.file}'", fgGreen, ": ", getCurrentExceptionMsg())
|
||||
quit(0)
|
||||
|
||||
|
||||
proc runFile(f: string) =
|
||||
var
|
||||
tokenizer = newLexer()
|
||||
parser = newParser()
|
||||
compiler = newCompiler()
|
||||
vm = newPeonVM()
|
||||
tokenizer.fillSymbolTable()
|
||||
try:
|
||||
vm.run(compiler.compile(parser.parse(tokenizer.lex(readFile(f), f), f), f))
|
||||
except LexingError:
|
||||
let exc = LexingError(getCurrentException())
|
||||
let relPos = tokenizer.getRelPos(exc.line)
|
||||
let line = tokenizer.getSource().splitLines()[exc.line - 1].strip()
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while parsing ", fgYellow, &"'{exc.file}'", fgRed, ", module ",
|
||||
fgYellow, &"'{exc.file}'", fgRed, ", line ", fgYellow, $exc.line, fgRed, " at ", fgYellow, &"'{exc.lexeme}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
styledEcho fgBlue, "Source line: " , fgDefault, line
|
||||
styledEcho fgCyan, " ".repeat(len("Source line: ")) & "^".repeat(relPos.stop - relPos.start)
|
||||
except ParseError:
|
||||
let exc = ParseError(getCurrentException())
|
||||
let lexeme = exc.token.lexeme
|
||||
let lineNo = exc.token.line
|
||||
let relPos = tokenizer.getRelPos(lineNo)
|
||||
let fn = parser.getCurrentFunction()
|
||||
let line = tokenizer.getSource().splitLines()[lineNo - 1].strip()
|
||||
var fnMsg = ""
|
||||
if fn != nil and fn.kind == funDecl:
|
||||
fnMsg &= &"in function '{FunDecl(fn).name.token.lexeme}'"
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while parsing ", fgYellow, &"'{exc.file}'", fgRed, ", module ",
|
||||
fgYellow, &"'{exc.file}'", fgRed, ", line ", fgYellow, $lineNo, fgRed, " at ", fgYellow, &"'{lexeme}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
styledEcho fgBlue, "Source line: " , fgDefault, line
|
||||
styledEcho fgCyan, " ".repeat(len("Source line: ")) & "^".repeat(relPos.stop - relPos.start)
|
||||
except CompileError:
|
||||
let exc = CompileError(getCurrentException())
|
||||
let lexeme = exc.node.token.lexeme
|
||||
let lineNo = exc.node.token.line
|
||||
let relPos = tokenizer.getRelPos(lineNo)
|
||||
let line = tokenizer.getSource().splitLines()[lineNo - 1].strip()
|
||||
var fn = compiler.getCurrentFunction()
|
||||
var fnMsg = ""
|
||||
if fn != nil and fn.kind == funDecl:
|
||||
fnMsg &= &"in function '{FunDecl(fn).name.token.lexeme}'"
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while compiling ", fgYellow, &"'{exc.file}'", fgRed, ", module ",
|
||||
fgYellow, &"'{exc.module}'", fgRed, ", line ", fgYellow, $lineNo, fgRed, " at ", fgYellow, &"'{lexeme}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
styledEcho fgBlue, "Source line: " , fgDefault, line
|
||||
styledEcho fgCyan, " ".repeat(len("Source line: ")) & "^".repeat(relPos.stop - relPos.start)
|
||||
except SerializationError:
|
||||
let exc = SerializationError(getCurrentException())
|
||||
stderr.styledWriteLine(fgRed, "A fatal error occurred while (de-)serializing", fgYellow, &"'{exc.file}'", fgGreen, ": ", getCurrentExceptionMsg())
|
||||
except IOError:
|
||||
stderr.styledWriteLine("An error occurred while trying to read ", fgYellow, &"'{f}'", fgRed, &": {getCurrentExceptionMsg()}")
|
||||
except OSError:
|
||||
stderr.styledWriteLine("An error occurred while trying to read ", fgYellow, &"'{f}'", fgRed, &": {osErrorMsg(osLastError())} [errno {osLastError()}]")
|
||||
|
||||
|
||||
when isMainModule:
|
||||
setControlCHook(proc () {.noconv.} = quit(0))
|
||||
let args = commandLineParams()
|
||||
if args.len() == 0:
|
||||
repl()
|
||||
else:
|
||||
runFile(args[0])
|
||||
|
||||
|
||||
proc fillSymbolTable(tokenizer: Lexer) =
|
||||
## Initializes the Lexer's symbol
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
## Builtin arithmetic operators for Peon
|
||||
|
||||
|
||||
operator `+`(a, b: int): int {
|
||||
#pragma[magic: AddInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `+`(a, b: uint): uint {
|
||||
#pragma[magic: AddUInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `+`(a, b: int32): int32 {
|
||||
#pragma[magic: AddInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `+`(a, b: uint32): uint32 {
|
||||
#pragma[magic: AddUInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `+`(a, b: int16): int16 {
|
||||
#pragma[magic: AddInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `+`(a, b: uint16): uint16 {
|
||||
#pragma[magic: AddUInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `+`(a, b: int8): int8 {
|
||||
#pragma[magic: AddInt8, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `+`(a, b: uint8): uint8 {
|
||||
#pragma[magic: AddUInt8, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: int): int {
|
||||
#pragma[magic: SubInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: uint): uint {
|
||||
#pragma[magic: SubUInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: int32): int32 {
|
||||
#pragma[magic: SubInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: uint32): uint32 {
|
||||
#pragma[magic: SubUInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: int16): int16 {
|
||||
#pragma[magic: SubInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: uint16): uint16 {
|
||||
#pragma[magic: SubUInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: int8): int8 {
|
||||
#pragma[magic: SubInt8, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `-`(a, b: uint8): uint8 {
|
||||
#pragma[magic: SubUInt8, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: int): int {
|
||||
#pragma[magic: MulInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: uint): uint {
|
||||
#pragma[magic: MulUInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: int32): int32 {
|
||||
#pragma[magic: MulInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: uint32): uint32 {
|
||||
#pragma[magic: MulUInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: int16): int16 {
|
||||
#pragma[magic: MulInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: uint16): uint16 {
|
||||
#pragma[magic: MulUInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: int8): int8 {
|
||||
#pragma[magic: MulInt8, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `*`(a, b: uint8): uint8 {
|
||||
#pragma[magic: MulUInt8, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: int): int {
|
||||
#pragma[magic: DivInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: uint): uint {
|
||||
#pragma[magic: DivUInt64, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: int32): int32 {
|
||||
#pragma[magic: DivInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: uint32): uint32 {
|
||||
#pragma[magic: DivUInt32, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: int16): int16 {
|
||||
#pragma[magic: DivInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: uint16): uint16 {
|
||||
#pragma[magic: DivUInt16, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: int8): int8 {
|
||||
#pragma[magic: DivInt8, pure]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
operator `/`(a, b: uint8): uint8 {
|
||||
#pragma[magic: DivUInt8, pure]
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
operator `+`(a: int): int {
|
||||
return a;
|
||||
}
|
||||
|
||||
+1;
|
|
@ -49,8 +49,7 @@ proc `$`*(self: Serialized): string =
|
|||
|
||||
proc error(self: Serializer, message: string) =
|
||||
## Raises a formatted SerializationError exception
|
||||
raise newException(SerializationError,
|
||||
&"A fatal error occurred while (de)serializing '{self.filename}' -> {message}")
|
||||
raise SerializationError(msg: message, file: self.filename)
|
||||
|
||||
|
||||
proc newSerializer*(self: Serializer = nil): Serializer =
|
||||
|
|
Loading…
Reference in New Issue