Added all missing comparison operators and fixed error reporting system
This commit is contained in:
parent
e01f1939bb
commit
e120352302
|
@ -692,6 +692,46 @@ proc dispatch*(self: PeonVM) =
|
|||
self.push(PeonObject(kind: Bool, boolean: self.pop().halfFloat == self.pop().halfFloat))
|
||||
of NotEqualFloat32:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().halfFloat != self.pop().halfFloat))
|
||||
of GreaterOrEqualInt64:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().long !>= self.pop().long))
|
||||
of LessOrEqualInt64:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().long <= self.pop().long))
|
||||
of GreaterOrEqualUInt64:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uLong !>= self.pop().uLong))
|
||||
of LessOrEqualUInt64:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uLong <= self.pop().uLong))
|
||||
of GreaterOrEqualInt32:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().`int` !>= self.pop().`int`))
|
||||
of LessOrEqualInt32:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().`int` <= self.pop().`int`))
|
||||
of GreaterOrEqualUInt32:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uInt !>= self.pop().uInt))
|
||||
of LessOrEqualUInt32:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uInt <= self.pop().uInt))
|
||||
of GreaterOrEqualInt16:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().short !>= self.pop().short))
|
||||
of LessOrEqualInt16:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().short <= self.pop().short))
|
||||
of GreaterOrEqualUInt16:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uShort !>= self.pop().uShort))
|
||||
of LessOrEqualUInt16:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uShort <= self.pop().uShort))
|
||||
of GreaterOrEqualInt8:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().tiny !>= self.pop().tiny))
|
||||
of LessOrEqualInt8:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().tiny <= self.pop().tiny))
|
||||
of GreaterOrEqualUInt8:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uTiny !>= self.pop().uTiny))
|
||||
of LessOrEqualUInt8:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().uTiny <= self.pop().uTiny))
|
||||
of GreaterOrEqualFloat64:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().`float` !>= self.pop().`float`))
|
||||
of LessOrEqualFloat64:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().`float` <= self.pop().`float`))
|
||||
of GreaterOrEqualFloat32:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().halfFloat !>= self.pop().halfFloat))
|
||||
of LessOrEqualFloat32:
|
||||
self.push(PeonObject(kind: Bool, boolean: self.pop().halfFloat <= self.pop().halfFloat))
|
||||
of SysClock64:
|
||||
# Pushes the value of a monotonic clock
|
||||
# as a 64 bit float onto the operand stack.
|
||||
|
|
|
@ -1103,6 +1103,46 @@ proc handleBuiltinFunction(self: Compiler, fn: Name, args: seq[Expression]) =
|
|||
self.emitByte(EqualFloat32)
|
||||
of "NotEqualFloat32":
|
||||
self.emitByte(NotEqualFloat32)
|
||||
of "GreaterOrEqualInt64":
|
||||
self.emitByte(GreaterOrEqualInt64)
|
||||
of "LessOrEqualInt64":
|
||||
self.emitByte(LessOrEqualInt64)
|
||||
of "GreaterOrEqualUInt64":
|
||||
self.emitByte(GreaterOrEqualUInt64)
|
||||
of "LessOrEqualUInt64":
|
||||
self.emitByte(LessOrEqualUInt64)
|
||||
of "GreaterOrEqualInt32":
|
||||
self.emitByte(GreaterOrEqualInt32)
|
||||
of "LessOrEqualInt32":
|
||||
self.emitByte(LessOrEqualInt32)
|
||||
of "GreaterOrEqualUInt32":
|
||||
self.emitByte(GreaterOrEqualUInt32)
|
||||
of "LessOrEqualUInt32":
|
||||
self.emitByte(LessOrEqualUInt32)
|
||||
of "GreaterOrEqualInt16":
|
||||
self.emitByte(GreaterOrEqualInt16)
|
||||
of "LessOrEqualInt16":
|
||||
self.emitByte(LessOrEqualInt16)
|
||||
of "GreaterOrEqualUInt16":
|
||||
self.emitByte(GreaterOrEqualUInt16)
|
||||
of "LessOrEqualUInt16":
|
||||
self.emitByte(LessOrEqualUInt16)
|
||||
of "GreaterOrEqualInt8":
|
||||
self.emitByte(GreaterOrEqualInt8)
|
||||
of "LessOrEqualInt8":
|
||||
self.emitByte(LessOrEqualInt8)
|
||||
of "GreaterOrEqualUInt8":
|
||||
self.emitByte(GreaterOrEqualUInt8)
|
||||
of "LessOrEqualUInt8":
|
||||
self.emitByte(LessOrEqualUInt8)
|
||||
of "GreaterOrEqualFloat64":
|
||||
self.emitByte(GreaterOrEqualFloat64)
|
||||
of "LessOrEqualFloat64":
|
||||
self.emitByte(LessOrEqualFloat64)
|
||||
of "GreaterOrEqualFloat32":
|
||||
self.emitByte(GreaterOrEqualFloat32)
|
||||
of "LessOrEqualFloat32":
|
||||
self.emitByte(LessOrEqualFloat32)
|
||||
of "SysClock64":
|
||||
self.emitByte(SysClock64)
|
||||
else:
|
||||
|
|
|
@ -237,7 +237,6 @@ proc peek(self: Lexer, distance: int = 0, length: int = 1): string =
|
|||
proc error(self: Lexer, message: string) =
|
||||
## Raises a lexing error with info
|
||||
## for error messages
|
||||
echo self.source[self.current - 50..self.current]
|
||||
raise LexingError(msg: message, line: self.line, file: self.file, lexeme: self.peek(), lexer: self)
|
||||
|
||||
|
||||
|
@ -297,9 +296,7 @@ proc createToken(self: Lexer, tokenType: TokenType) =
|
|||
tok.line = self.line
|
||||
tok.spaces = self.spaces
|
||||
self.spaces = 0
|
||||
tok.pos = (start: self.start, stop: self.current)
|
||||
if len(tok.lexeme) != tok.pos.stop - tok.pos.start:
|
||||
self.error("invalid state: len(tok.lexeme) != tok.pos.stop - tok.pos.start (this is most likely a compiler bug!)")
|
||||
tok.pos = (start: self.start, stop: self.current - 1)
|
||||
self.tokens.add(tok)
|
||||
|
||||
|
||||
|
@ -616,6 +613,7 @@ proc next(self: Lexer) =
|
|||
while not (self.match("\n") or self.done()):
|
||||
discard self.step()
|
||||
self.createToken(Comment)
|
||||
self.incLine()
|
||||
else:
|
||||
self.createToken(Pragma)
|
||||
else:
|
||||
|
|
|
@ -177,6 +177,26 @@ type
|
|||
GreaterThanFloat32,
|
||||
EqualFloat32,
|
||||
NotEqualFloat32,
|
||||
GreaterOrEqualInt64,
|
||||
LessOrEqualInt64,
|
||||
GreaterOrEqualUInt64,
|
||||
LessOrEqualUInt64,
|
||||
GreaterOrEqualInt32,
|
||||
LessOrEqualInt32,
|
||||
GreaterOrEqualUInt32,
|
||||
LessOrEqualUInt32,
|
||||
GreaterOrEqualInt16,
|
||||
LessOrEqualInt16,
|
||||
GreaterOrEqualUInt16,
|
||||
LessOrEqualUInt16,
|
||||
GreaterOrEqualInt8,
|
||||
LessOrEqualInt8,
|
||||
GreaterOrEqualUInt8,
|
||||
LessOrEqualUInt8,
|
||||
GreaterOrEqualFloat64,
|
||||
LessOrEqualFloat64,
|
||||
GreaterOrEqualFloat32,
|
||||
LessOrEqualFloat32,
|
||||
SysClock64,
|
||||
## Basic stack operations
|
||||
Pop, # Pops an element off the stack and discards it
|
||||
|
@ -253,6 +273,27 @@ const simpleInstructions* = {Return, LoadNil,
|
|||
NotEqualUInt8, LessThanFloat64, GreaterThanFloat64,
|
||||
EqualFloat64,NotEqualFloat64, LessThanFloat32,
|
||||
GreaterThanFloat32, EqualFloat32, NotEqualFloat32,
|
||||
GreaterOrEqualInt64,
|
||||
LessOrEqualInt64,
|
||||
GreaterOrEqualUInt64,
|
||||
LessOrEqualUInt64,
|
||||
GreaterOrEqualInt32,
|
||||
LessOrEqualInt32,
|
||||
GreaterOrEqualUInt32,
|
||||
LessOrEqualUInt32,
|
||||
GreaterOrEqualInt16,
|
||||
LessOrEqualInt16,
|
||||
GreaterOrEqualUInt16,
|
||||
LessOrEqualUInt16,
|
||||
GreaterOrEqualInt8,
|
||||
LessOrEqualInt8,
|
||||
GreaterOrEqualUInt8,
|
||||
LessOrEqualUInt8,
|
||||
GreaterOrEqualFloat64,
|
||||
LessOrEqualFloat64,
|
||||
GreaterOrEqualFloat32,
|
||||
LessOrEqualFloat32,
|
||||
SysClock64,
|
||||
}
|
||||
|
||||
# Constant instructions are instructions that operate on the bytecode constant table
|
||||
|
|
|
@ -208,6 +208,7 @@ proc step(self: Parser, n: int = 1): Token =
|
|||
|
||||
proc error(self: Parser, message: string, token: Token = nil) {.raises: [ParseError].} =
|
||||
## Raises a ParseError exception
|
||||
echo (if token.isNil(): self.getCurrentToken() else: token)[]
|
||||
raise ParseError(msg: message, token: if token.isNil(): self.getCurrentToken() else: token, file: self.file, module: self.getModule(), parser: self)
|
||||
|
||||
|
||||
|
|
26
src/main.nim
26
src/main.nim
|
@ -141,11 +141,11 @@ proc repl(vm: PeonVM = newPeonVM()) =
|
|||
except LexingError:
|
||||
input = ""
|
||||
let exc = LexingError(getCurrentException())
|
||||
let relPos = tokenizer.getRelPos(exc.line)
|
||||
let line = tokenizer.getSource().splitLines()[exc.line - 1].strip(chars={'\n'})
|
||||
let relPos = exc.lexer.getRelPos(exc.line)
|
||||
let line = exc.lexer.getSource().splitLines()[exc.line - 1].strip(chars={'\n'})
|
||||
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.escape()}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
fgYellow, &"'{exc.file.extractFilename()}'", fgRed, ", line ", fgYellow, $exc.line, fgRed, " at ", fgYellow, &"'{exc.lexeme.escape()}'",
|
||||
fgRed, ": ", fgGreen , getCurrentExceptionMsg())
|
||||
styledEcho fgBlue, "Source line: " , fgDefault, line
|
||||
styledEcho fgCyan, " ".repeat(len("Source line: ")) & "^".repeat(relPos.stop - relPos.start)
|
||||
except ParseError:
|
||||
|
@ -153,30 +153,30 @@ proc repl(vm: PeonVM = newPeonVM()) =
|
|||
let exc = ParseError(getCurrentException())
|
||||
let lexeme = exc.token.lexeme
|
||||
let lineNo = exc.token.line
|
||||
let relPos = tokenizer.getRelPos(lineNo)
|
||||
let relPos = exc.parser.getRelPos(lineNo)
|
||||
let fn = parser.getCurrentFunction()
|
||||
let line = tokenizer.getSource().splitLines()[lineNo - 1].strip(chars={'\n'})
|
||||
let line = exc.parser.getSource().splitLines()[lineNo - 1].strip(chars={'\n'})
|
||||
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())
|
||||
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 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(chars={'\n'})
|
||||
var fn = compiler.getCurrentFunction()
|
||||
let relPos = exc.compiler.getRelPos(lineNo)
|
||||
let line = exc.compiler.getSource().splitLines()[lineNo - 1].strip(chars={'\n'})
|
||||
var fn = exc.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())
|
||||
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:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import std;
|
||||
|
||||
# int64
|
||||
print(3 > 2); # true
|
||||
print(2 < 3); # true
|
||||
|
@ -9,6 +8,10 @@ print(2 != 3); # true
|
|||
print(3 != 2); # true
|
||||
print(3 == 2); # false
|
||||
print(2 == 3); # false
|
||||
print(2 <= 3); # true
|
||||
print(3 >= 2); # true
|
||||
print(2 >= 3); # false
|
||||
print(3 <= 2); # false
|
||||
# uint64
|
||||
var x = 3'u64;
|
||||
var y = 2'u64;
|
||||
|
@ -20,6 +23,10 @@ print(y != x); # true
|
|||
print(x != y); # true
|
||||
print(x == y); # false
|
||||
print(y == x); # false
|
||||
print(y <= x); # true
|
||||
print(x >= y); # true
|
||||
print(y >= x); # false
|
||||
print(x <= y); # false
|
||||
# int32
|
||||
var x1 = 3'i32;
|
||||
var y1 = 2'i32;
|
||||
|
@ -31,6 +38,10 @@ print(y1 != x1); # true
|
|||
print(x1 != y1); # true
|
||||
print(x1 == y1); # false
|
||||
print(y1 == x1); # false
|
||||
print(y1 <= x1); # true
|
||||
print(x1 >= y1); # true
|
||||
print(y1 >= x1); # false
|
||||
print(x1 <= y1); # false
|
||||
# uint32
|
||||
var x2 = 3'u32;
|
||||
var y2 = 2'u32;
|
||||
|
@ -42,6 +53,10 @@ print(y2 != x2); # true
|
|||
print(x2 != y2); # true
|
||||
print(x2 == y2); # false
|
||||
print(y2 == x2); # false
|
||||
print(y2 <= x2); # true
|
||||
print(x2 >= y2); # true
|
||||
print(y2 >= x2); # false
|
||||
print(x2 <= y2); # false
|
||||
# int16
|
||||
var x3 = 3'i16;
|
||||
var y3 = 2'i16;
|
||||
|
@ -53,6 +68,10 @@ print(y3 != x3); # true
|
|||
print(x3 != y3); # true
|
||||
print(x3 == y3); # false
|
||||
print(y3 == x3); # false
|
||||
print(y3 <= x3); # true
|
||||
print(x3 >= y3); # true
|
||||
print(y3 >= x3); # false
|
||||
print(x3 <= y3); # false
|
||||
# uint16
|
||||
var x4 = 3'u16;
|
||||
var y4 = 2'u16;
|
||||
|
@ -64,6 +83,10 @@ print(y4 != x4); # true
|
|||
print(x4 != y4); # true
|
||||
print(x4 == y4); # false
|
||||
print(y4 == x4); # false
|
||||
print(y4 <= x4); # true
|
||||
print(x4 >= y4); # true
|
||||
print(y4 >= x4); # false
|
||||
print(x4 <= y4); # false
|
||||
# int8
|
||||
var x5 = 3'i8;
|
||||
var y5 = 2'i8;
|
||||
|
@ -75,6 +98,10 @@ print(y5 != x5); # true
|
|||
print(x5 != y5); # true
|
||||
print(x5 == y5); # false
|
||||
print(y5 == x5); # false
|
||||
print(y5 <= x5); # true
|
||||
print(x5 >= y5); # true
|
||||
print(y5 >= x5); # false
|
||||
print(x5 <= y5); # false
|
||||
# uint8
|
||||
var x6 = 3'u8;
|
||||
var y6 = 2'u8;
|
||||
|
@ -86,6 +113,10 @@ print(y6 != x6); # true
|
|||
print(x6 != y6); # true
|
||||
print(x6 == y6); # false
|
||||
print(y6 == x6); # false
|
||||
print(y6 <= x6); # true
|
||||
print(x6 >= y6); # true
|
||||
print(y6 >= x6); # false
|
||||
print(x6 <= y6); # false
|
||||
# float64
|
||||
var x7 = 3.0;
|
||||
var y7 = 2.0;
|
||||
|
@ -97,6 +128,10 @@ print(y7 != x7); # true
|
|||
print(x7 != y7); # true
|
||||
print(x7 == y7); # false
|
||||
print(y7 == x7); # false
|
||||
print(y7 <= x7); # true
|
||||
print(x7 >= y7); # true
|
||||
print(y7 >= x7); # false
|
||||
print(x7 <= y7); # false
|
||||
# float32
|
||||
var x8 = 3'f32;
|
||||
var y8 = 2'f32;
|
||||
|
@ -108,3 +143,7 @@ print(y8 != x8); # true
|
|||
print(x8 != y8); # true
|
||||
print(x8 == y8); # false
|
||||
print(y8 == x8); # false
|
||||
print(y8 <= x8); # true
|
||||
print(x8 >= y8); # true
|
||||
print(y8 >= x8); # false
|
||||
print(x8 <= y8); # false
|
||||
|
|
99
tests/std.pn
99
tests/std.pn
|
@ -408,6 +408,105 @@ operator `!=`*(a, b: float32): bool {
|
|||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: int): bool {
|
||||
#pragma[magic: "GreaterOrEqualInt64", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: int): bool {
|
||||
#pragma[magic: "LessOrEqualInt64", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: uint64): bool {
|
||||
#pragma[magic: "GreaterOrEqualUInt64", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: uint64): bool {
|
||||
#pragma[magic: "LessOrEqualUInt64", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: int32): bool {
|
||||
#pragma[magic: "GreaterOrEqualInt32", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: int32): bool {
|
||||
#pragma[magic: "LessOrEqualInt32", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: uint32): bool {
|
||||
#pragma[magic: "GreaterOrEqualUInt32", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: uint32): bool {
|
||||
#pragma[magic: "LessOrEqualUInt32", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: int16): bool {
|
||||
#pragma[magic: "GreaterOrEqualInt16", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: int16): bool {
|
||||
#pragma[magic: "LessOrEqualInt16", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: uint16): bool {
|
||||
#pragma[magic: "GreaterOrEqualUInt16", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: uint16): bool {
|
||||
#pragma[magic: "LessOrEqualUInt16", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: int8): bool {
|
||||
#pragma[magic: "GreaterOrEqualInt8", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: int8): bool {
|
||||
#pragma[magic: "LessOrEqualInt8", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: uint8): bool {
|
||||
#pragma[magic: "GreaterOrEqualUInt8", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: uint8): bool {
|
||||
#pragma[magic: "LessOrEqualUInt8", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: float): bool {
|
||||
#pragma[magic: "GreaterOrEqualFloat64", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: float): bool {
|
||||
#pragma[magic: "LessOrEqualFloat64", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `>=`*(a, b: float32): bool {
|
||||
#pragma[magic: "GreaterOrEqualFloat32", pure]
|
||||
}
|
||||
|
||||
|
||||
operator `<=`*(a, b: float32): bool {
|
||||
#pragma[magic: "LessOrEqualFloat32", pure]
|
||||
}
|
||||
|
||||
# Assignment operator
|
||||
# TODO
|
||||
#operator `=`[T](a: var T, b: T) {
|
||||
|
|
Loading…
Reference in New Issue