From 9ef80535f319c736d51f9ea3ce51e28c7cc69af6 Mon Sep 17 00:00:00 2001 From: Mattia Giambirtone Date: Tue, 11 Oct 2022 09:52:49 +0200 Subject: [PATCH] Minor fixes to operator system and updated compiler error messages --- src/frontend/compiler.nim | 2 +- src/frontend/lexer.nim | 2 +- src/frontend/parser.nim | 10 +++++----- tests/generics.pn | 4 +++- tests/std.pn | 10 ++++++++++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/frontend/compiler.nim b/src/frontend/compiler.nim index bf43e4e..f3d1f1a 100644 --- a/src/frontend/compiler.nim +++ b/src/frontend/compiler.nim @@ -838,7 +838,7 @@ proc matchImpl(self: Compiler, name: string, kind: Type): Name = elif impl.len() > 1: var msg = &"multiple matching implementations of '{name}' found:\n" for fn in reversed(impl): - msg &= &"- '{fn.name.token.lexeme}' at line {fn.line} of type {self.typeToStr(fn.valueType)}\n" + msg &= &"- '{fn.name.token.lexeme}' in '{fn.owner}' at line {fn.line} of type {self.typeToStr(fn.valueType)}\n" self.error(msg) return impl[0] diff --git a/src/frontend/lexer.nim b/src/frontend/lexer.nim index 6d24a46..5315235 100644 --- a/src/frontend/lexer.nim +++ b/src/frontend/lexer.nim @@ -530,7 +530,7 @@ proc parseBackticks(self: Lexer) = ## parser complaining about syntax ## errors while not self.match("`") and not self.done(): - if self.peek().isAlphaNumeric() or self.symbols.existsSymbol(self.peek()): + if self.peek().isAlphaNumeric() or self.symbols.existsSymbol(self.peek()) or self.peek() in ["&", "|"]: discard self.step() continue self.error(&"unexpected character: '{self.peek()}'") diff --git a/src/frontend/parser.nim b/src/frontend/parser.nim index fefafbb..9225137 100644 --- a/src/frontend/parser.nim +++ b/src/frontend/parser.nim @@ -121,6 +121,10 @@ proc addOperator(self: OperatorTable, lexeme: string) = var prec = Power if lexeme.len() >= 2 and lexeme[^2..^1] in ["->", "~>", "=>"]: prec = Arrow + elif lexeme in ["and", "&"]: + prec = Precedence.And + elif lexeme in ["or", "|"]: + prec = Precedence.Or elif lexeme.endsWith("=") and lexeme[0] notin {'<', '>', '!', '?', '~', '='} or lexeme == "=": prec = Assign elif lexeme[0] in {'$', } or lexeme == "**": @@ -131,10 +135,6 @@ proc addOperator(self: OperatorTable, lexeme: string) = prec = Addition elif lexeme[0] in {'<', '>', '=', '!'}: prec = Compare - elif lexeme == "and": - prec = Precedence.And - elif lexeme == "or": - prec = Precedence.Or self.tokens.add(lexeme) self.precedence[prec].add(lexeme) @@ -144,6 +144,7 @@ proc getPrecedence(self: OperatorTable, lexeme: string): Precedence = for (prec, operators) in self.precedence.pairs(): if lexeme in operators: return prec + return Precedence.None proc newParser*: Parser = @@ -401,7 +402,6 @@ proc makeCall(self: Parser, callee: Expression): CallExpr = argument = self.expression() if argument.kind == binaryExpr and BinaryExpr(argument).operator.lexeme == "=": # TODO: This will explode with slices! - echo argument if IdentExpr(BinaryExpr(argument).a) in argNames: self.error("duplicate keyword argument in call") argNames.add(IdentExpr(BinaryExpr(argument).a)) diff --git a/tests/generics.pn b/tests/generics.pn index acf9ebb..62fa781 100644 --- a/tests/generics.pn +++ b/tests/generics.pn @@ -1,3 +1,5 @@ +import std; + operator `+`(a, b: int): int { #pragma[magic: "AddInt64", pure] } @@ -8,7 +10,7 @@ operator `+`(a, b: int32): int32 { } -fn sum[T](a, b: T): T { +fn sum[T: int | int32](a, b: T): T { return a + b; } diff --git a/tests/std.pn b/tests/std.pn index 846214d..ceffca2 100644 --- a/tests/std.pn +++ b/tests/std.pn @@ -535,6 +535,16 @@ operator `or`*(a, b: bool): bool { } +operator `&`*(a, b: bool): bool { + #pragma[magic: "LogicalAnd", pure] +} + + +operator `|`*(a, b: bool): bool { + #pragma[magic: "LogicalOr", pure] +} + + # Assignment operators operator `=`*[T: Any](a: var T, b: T) {