From adde05d5c2994b15cb51ca1b327270455ddeab02 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 2 Jun 2026 02:59:38 +0000 Subject: [PATCH 1/3] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'effekt-nix': 'github:jiribenes/effekt-nix/8029cdc' (2026-01-19) → 'github:jiribenes/effekt-nix/60af21b' (2026-05-18) • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/bde0902' (2026-01-19) → 'github:NixOS/nixpkgs/4df1b88' (2026-06-01) --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 30c191e..033fc01 100644 --- a/flake.lock +++ b/flake.lock @@ -11,11 +11,11 @@ "sbt-derivation": "sbt-derivation" }, "locked": { - "lastModified": 1768810797, - "narHash": "sha256-BC4xoA9PBJTip/qjpnT7Nh4mshIrvImxVpHOTkrBFtI=", + "lastModified": 1779116722, + "narHash": "sha256-F6tiXWuWOT+s5j04j4W+x8x541ZzjjUm7HxEHTQu0Qw=", "owner": "jiribenes", "repo": "effekt-nix", - "rev": "8029cdce05836a55fb4e7dd96665541dc6abecd8", + "rev": "60af21b260a87f58da8674240084ed0fb85a4b45", "type": "github" }, "original": { @@ -44,11 +44,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1768783163, - "narHash": "sha256-tLj4KcRDLakrlpvboTJDKsrp6z2XLwyQ4Zmo+w8KsY4=", + "lastModified": 1780336545, + "narHash": "sha256-vhVhuXzFrIOfcssC/9hDHx7MHzDKjF3keHuREOQqQiQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bde09022887110deb780067364a0818e89258968", + "rev": "4df1b885d76a54e1aa1a318f8d16fd6005b6401f", "type": "github" }, "original": { From 9726b7be34ee2eb573904f0fd8e2ad921a6270ce Mon Sep 17 00:00:00 2001 From: Martin Ilgner Date: Mon, 8 Jun 2026 10:49:05 +0200 Subject: [PATCH 2/3] Fix ambiguous overloads and renamed lib stuff --- src/lib/desugar/sugar.effekt | 2 +- src/lib/interpreter/eval.effekt | 6 +- src/lib/interpreter/handlers.effekt | 2 +- src/lib/lexer/lexer.effekt | 142 ++++++++++++------------- src/lib/parser/parser.effekt | 28 ++--- src/lib/runner/runParser.effekt | 4 +- src/lib/runner/runRepl.effekt | 4 +- src/lib/shared/commonHandlers.effekt | 2 +- src/lib/typechecker/handlers.effekt | 2 +- src/lib/typechecker/typecheck.effekt | 14 +-- src/lib/typechecker/unification.effekt | 4 +- src/tests/testInterpreter.effekt | 10 +- src/tests/testTypechecker.effekt | 62 +++++------ 13 files changed, 141 insertions(+), 141 deletions(-) diff --git a/src/lib/desugar/sugar.effekt b/src/lib/desugar/sugar.effekt index aa487fc..149e9bc 100644 --- a/src/lib/desugar/sugar.effekt +++ b/src/lib/desugar/sugar.effekt @@ -99,7 +99,7 @@ def desugarStmt(s: surfaceAst::Stmt): coreAst::Stmt / { Exception[DesugarError], val binaryExpr = operator match { case PlusAssign() => surfaceAst::AddExpr(variableExpr, value, pos) case MinusAssign() => surfaceAst::SubExpr(variableExpr, value, pos) - case _ => do raise(DesugarError(), "unsupported compound assignment operator in desugaring: " ++ operator.show) + case _ => do raise(DesugarError(), "unsupported compound assignment operator in desugaring: " ++ helpers::show(operator)) } coreAst::AssignStmt(name, desugarExpr(binaryExpr), pos) } diff --git a/src/lib/interpreter/eval.effekt b/src/lib/interpreter/eval.effekt index 7319b93..5d45fc3 100644 --- a/src/lib/interpreter/eval.effekt +++ b/src/lib/interpreter/eval.effekt @@ -101,14 +101,14 @@ def evalExpr(expr: Expr): Value / { Context[Address], Store, Exception[RuntimeEr if (r != 0) { VInt(l / r) } else { - do raise(errors::RuntimeError(), "Division by zero at " ++ do getPos().show) + do raise(errors::RuntimeError(), "Division by zero at " ++ helpers::show(do commonEffects::getPos())) } } case (VDouble(l), VDouble(r)) => { if (r != 0.0) { VDouble(l / r) } else { - do raise(errors::RuntimeError(), "Division by zero at " ++ do getPos().show) + do raise(errors::RuntimeError(), "Division by zero at " ++ helpers::show(do commonEffects::getPos())) } } case _ => do raise(errors::RuntimeError(), "Type error in division") @@ -368,7 +368,7 @@ def evalExpr(expr: Expr): Value / { Context[Address], Store, Exception[RuntimeEr } - case _ => raise(errors::RuntimeError(), "trying to call a non-function value at " ++ pos.show) + case _ => raise(errors::RuntimeError(), "trying to call a non-function value at " ++ helpers::show(pos)) } } } diff --git a/src/lib/interpreter/handlers.effekt b/src/lib/interpreter/handlers.effekt index 08fc391..3c2e2f5 100644 --- a/src/lib/interpreter/handlers.effekt +++ b/src/lib/interpreter/handlers.effekt @@ -22,7 +22,7 @@ def handleRuntimeContext[R](initEnv: Map[String, Address]) { prog: => R / { Cont def lookup(name) = { context.get(name) match { case Some(addr) => resume(addr) - case None() => do raise(errors::RuntimeError(), "Undefined variable '" ++ name ++ "' at " ++ do getPos().show) + case None() => do raise(errors::RuntimeError(), "Undefined variable '" ++ name ++ "' at " ++ helpers::show(do commonEffects::getPos())) } } diff --git a/src/lib/lexer/lexer.effekt b/src/lib/lexer/lexer.effekt index b1b1436..1d2c729 100644 --- a/src/lib/lexer/lexer.effekt +++ b/src/lib/lexer/lexer.effekt @@ -34,27 +34,8 @@ def scanWithPos[R]() { prog: => R / { Scan[Char], Positioning } }: R / Scan[Char } } - try { prog() } with Scan[Char] { - def peek() = resume { - lastSeen match { - // If we already cached a peeked character, return it - case Some(c) => return c - - // We rethrow the peek to the *underlying* Scan handler by calling `do peek()`. - // This ultimately causes the lower-level scanner to perform `read()`, - // which is handled by the filesystem. - // - // We intercept the returned character and store it in `lastSeen`, - // but we do NOT advance the position yet (because peek does not consume) - case None() => { - val c = do Scan::peek() - lastSeen = Some(c) - return c - } - } - } - - def skip() = resume { + try { prog() } with next[Char] { + resume { lastSeen match { // Case 1: a previous peek has cached the next character. // That means this skip is *consuming* exactly that character. @@ -62,22 +43,41 @@ def scanWithPos[R]() { prog: => R / { Scan[Char], Positioning } }: R / Scan[Char // We rethrow the skip to the underlying handler (`do skip()`). // That underlying skip will not trigger another read, since the lower // scanner already buffered the character during peek. - do skip() + do stream::next() // Now we know the character was consumed → update position. updatePos(c) // Clear peek cache lastSeen = None() - return () + return c } // Case 2: skip happens without a prior peek. // That means we must read the character now in order to know what is consumed case None() => { // We first rethrow a peek to underlying handler to obtain the character - val c = do Scan::peek() + val c = do stream::peek() // Then we perform the actual skip (again rethrown) updatePos(c) - do skip() - return () + do stream::next() + return c + } + } + } + } with peek[Char] { + resume { + lastSeen match { + // If we already cached a peeked character, return it + case Some(c) => return c + + // We rethrow the peek to the *underlying* Scan handler by calling `do peek()`. + // This ultimately causes the lower-level scanner to perform `read()`, + // which is handled by the filesystem. + // + // We intercept the returned character and store it in `lastSeen`, + // but we do NOT advance the position yet (because peek does not consume) + case None() => { + val c = do stream::peek() + lastSeen = Some(c) + return c } } } @@ -128,7 +128,7 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning // checks if the next char is alphabetic (used to disallow identifiers starting with numbers) def checkInvalidTrailingAlpha(): Bool / { Scan[Char], stop } = { try { - val next = do Scan::peek() + val next = do stream::peek() next.isAlphabetic || next == '_' } with stop { false @@ -137,13 +137,13 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning // reads a decimal number (integer part only) def readNumberToken(pos: Position): Token / { Scan[Char], stop } = { - val integerPart = try { readDecimal() } with fail { raise(LexerError(), "invalid number at " ++ pos.show) } - val next = try { do Scan::peek() } with stop { ' ' } + val integerPart = try { readDecimal() } with fail { raise(LexerError(), "invalid number at " ++ helpers::show(pos)) } + val next = try { do stream::peek() } with stop { ' ' } // check for fractional part if (next == '.') { // consume '.' - do Scan::skip() + do stream::next() // read fractional part as string to avoid precision issues like 123.000001 val fractionalPart = string::collect { @@ -151,11 +151,11 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning } if (fractionalPart == "") { - do raise(LexerError(), "Expected digit after '.' at " ++ pos.show) + do raise(LexerError(), "Expected digit after '.' at " ++ helpers::show(pos)) } if (checkInvalidTrailingAlpha()) { - do raise(LexerError(), "Invalid identifier starting with number at " ++ pos.show) + do raise(LexerError(), "Invalid identifier starting with number at " ++ helpers::show(pos)) } val doubleVal = stringToDouble(integerPart.show ++ "." ++ fractionalPart) @@ -163,7 +163,7 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning } else { if (checkInvalidTrailingAlpha()) { val rest = string::collect { readMany { c => c.isAlphanumeric } } - do raise(LexerError(), "invalid char at " ++ pos.show ++ " in " ++ "'" ++ integerPart.show ++ rest ++ "'") + do raise(LexerError(), "invalid char at " ++ helpers::show(pos) ++ " in " ++ "'" ++ integerPart.show ++ rest ++ "'") } Token(Integer(integerPart), pos) } @@ -171,21 +171,21 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning def readStringLikeToken(pos: Position, delim: Char): Token / { Scan[Char], stop, Exception[LexerError] } = { // consume opening " - do Scan::skip() + do stream::next() // collect string content, handling escape sequences val strValue = try { string::collect { def loop(): Unit = { - val c = do Scan::peek() + val c = do stream::peek() if (c == delim) { () // end of string literal, stop collecting } else if (c == '\\') { - do Scan::skip() // consume the \ - val escaped = do Scan::peek() - do Scan::skip() // consume the char after the \ + do stream::next() // consume the \ + val escaped = do stream::peek() + do stream::next() // consume the char after the \ // handle escape sequences escaped match { @@ -202,7 +202,7 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning } loop() } else { - do Scan::skip() + do stream::next() do emit(c) // normal char loop() } @@ -210,12 +210,12 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning loop() } } with stop { - do raise(LexerError(), "unterminated string literal at " ++ pos.show) + do raise(LexerError(), "unterminated string literal at " ++ helpers::show(pos)) } // expect closing " - if (do Scan::peek() == delim) { - do Scan::skip() + if (do stream::peek() == delim) { + do stream::next() } else { do raise(LexerError(), "Expected " ++ delim.show ++ " at end of string") } @@ -226,10 +226,10 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning // always skip whitespace skipWhitespace() - val pos = do getPos() + val pos = do commonEffects::getPos() // one char lookahead - val c = do Scan::peek() + val c = do stream::peek() if (c.isAlphabetic) { readIdentifierOrKeyword(pos) @@ -241,86 +241,86 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning readStringLikeToken(pos, '\'') } else if (c == '=') { // consume first char - do Scan::skip() + do stream::next() // second lookahead to recognize two char tokens - val next = do Scan::peek() + val next = do stream::peek() if(next == '=') { - do Scan::skip() + do stream::next() Token(Equal(), pos) } else { Token(Assign(), pos) } } else if (c == '!') { // consume '!' and check for '!=' - do Scan::skip() + do stream::next() readIf('=') Token(NotEqual(), pos) } else if (c == '<') { - do Scan::skip() - val next = do Scan::peek() + do stream::next() + val next = do stream::peek() if (next == '=') { - do Scan::skip() + do stream::next() Token(LessEqual(), pos) } else { Token(Less(), pos) } } else if (c == '>') { - do Scan::skip() - val next = do Scan::peek() + do stream::next() + val next = do stream::peek() if (next == '=') { - do Scan::skip() + do stream::next() Token(GreaterEqual(), pos) } else { Token(Greater(), pos) } } else if (c == '+') { - do Scan::skip() - val next = do Scan::peek() + do stream::next() + val next = do stream::peek() if (next == '=') { - do Scan::skip() + do stream::next() Token(PlusAssign(), pos) } else { Token(Plus(), pos) } } else if (c == '-') { - do Scan::skip() - val next = do Scan::peek() + do stream::next() + val next = do stream::peek() if (next == '=') { - do Scan::skip() + do stream::next() Token(MinusAssign(), pos) } else if (next == '>') { - do Scan::skip() + do stream::next() Token(Arrow(), pos) } else { Token(Minus(), pos) } } else if (c == '*') { - do Scan::skip() + do stream::next() Token(Mult(), pos) } else if (c == '/') { - do Scan::skip() + do stream::next() Token(Div(), pos) } else if (c == '(') { - do Scan::skip() + do stream::next() Token(LParen(), pos) } else if (c == ')') { - do Scan::skip() + do stream::next() Token(RParen(), pos) } else if (c == '{') { - do Scan::skip() + do stream::next() Token(LBrace(), pos) } else if (c == '}') { - do Scan::skip() + do stream::next() Token(RBrace(), pos) } else if (c == ':') { - do Scan::skip() + do stream::next() Token(Colon(), pos) } else if (c == ',') { - do Scan::skip() + do stream::next() Token(Comma(), pos) } else { - do raise(LexerError(), "can not tokenize char: " ++ "'" ++ c.show ++ "'" ++ " at " ++ pos.show) + do raise(LexerError(), "can not tokenize char: " ++ "'" ++ c.show ++ "'" ++ " at " ++ helpers::show(pos)) } } @@ -335,7 +335,7 @@ def lexer[R]() { program: => R / Lexer[Token] }: R / { Scan[Char], Positioning, try { nextToken() } with stop { - Token(EOF(), do getPos()) + Token(EOF(), do commonEffects::getPos()) } } diff --git a/src/lib/parser/parser.effekt b/src/lib/parser/parser.effekt index 0fb6eae..55adf4a 100644 --- a/src/lib/parser/parser.effekt +++ b/src/lib/parser/parser.effekt @@ -15,7 +15,7 @@ import src/lib/typechecker/types /// Parentheses are handled here so that ( ... ) produces a nested expression. def parsePrimaryRaw(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case Integer(n) => { do next() @@ -61,7 +61,7 @@ def parsePrimaryRaw(): Expr / { Lexer[Token], Positioning, Exception[ParseError] FunExpr(params, retType, body, pos) } - case _ => do raise(ParseError(), "expected expression at position " ++ token.position.show ++ " but got " ++ token.kind.show) + case _ => do raise(ParseError(), "expected expression at position " ++ helpers::show(token.position) ++ " but got " ++ helpers::show(token.kind)) } } @@ -72,7 +72,7 @@ def parsePrimary(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } def go(current: Expr): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { if (check(LParen())) { - val callPos = do getPos() + val callPos = do commonEffects::getPos() do next() val args = parseCommaList { parseArgument } expect(RParen()) @@ -90,7 +90,7 @@ def parsePrimary(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } /// it falls back to parsePrimary(). def parseUnary(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case Not() => { do next() @@ -112,7 +112,7 @@ def parseUnary(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = def parseAnd(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { def go(left: Expr): Expr / { Lexer[Token], Positioning } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case And() => { do next() @@ -131,7 +131,7 @@ def parseAnd(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { def parseOr(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { def go(left: Expr): Expr / { Lexer[Token], Positioning } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case Or() => { do next() @@ -154,7 +154,7 @@ def parseMultiplicative(): Expr / { Lexer[Token], Positioning, Exception[ParseEr def go(left: Expr): Expr / { Lexer[Token], Positioning } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case Mult() => { do next() @@ -181,7 +181,7 @@ def parseAdditive(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } def go(left: Expr): Expr / { Lexer[Token], Positioning } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case Plus() => { do next() @@ -207,7 +207,7 @@ def parseAdditive(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } def parseComparison(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { val left = parseAdditive() val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() // no comparison operator: return left as is if (not(isComparisonOp(token.kind))){ @@ -253,7 +253,7 @@ def parseComparison(): Expr / { Lexer[Token], Positioning, Exception[ParseError] /// Example: `42 if x > 0 else -1` def parseIfExpression(): Expr / { Lexer[Token], Positioning, Exception[ParseError] } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case If() => { do next() @@ -286,7 +286,7 @@ def parseExpression(): Expr / { Lexer[Token], Positioning, Exception[ParseError] /// - `parseBlock` is used to parse the lists of statements inside braces. def parseStmt(): Stmt / { Lexer[Token], Positioning, Exception[ParseError] } = { val token = do peek() - val pos = do getPos() + val pos = do commonEffects::getPos() token.kind match { case Val() => { do next() @@ -465,9 +465,9 @@ def parseType(): Type / { Lexer[Token], Exception[ParseError], Positioning } = { [extractType(id)] } - case LowerIdentifier(id) => raise(ParseError(), "syntax error at position " ++ token.position.show ++ ": type annotations must start with upper case char") + case LowerIdentifier(id) => raise(ParseError(), "syntax error at position " ++ helpers::show(token.position) ++ ": type annotations must start with upper case char") - case _ => raise(ParseError(), "expected type name (UpperIdentifier) at position " ++ token.position.show ++ " but got " ++ token.kind.show) + case _ => raise(ParseError(), "expected type name (UpperIdentifier) at position " ++ helpers::show(token.position) ++ " but got " ++ helpers::show(token.kind)) } val nextToken = do peek() @@ -479,7 +479,7 @@ def parseType(): Type / { Lexer[Token], Exception[ParseError], Positioning } = { } case _ => paramTypes match { case Cons(single, Nil()) => single - case _ => raise(ParseError(), "expected '->' for function type at position " ++ nextToken.position.show) + case _ => raise(ParseError(), "expected '->' for function type at position " ++ helpers::show(nextToken.position)) } } } diff --git a/src/lib/runner/runParser.effekt b/src/lib/runner/runParser.effekt index f45cffe..5286eb1 100644 --- a/src/lib/runner/runParser.effekt +++ b/src/lib/runner/runParser.effekt @@ -28,7 +28,7 @@ def parseAndDesugar(): PipelineResult[Program] / { Lexer[Token], Exception[Parse def runParsing(input: String) : PipelineResult[Program] = { try { with string::feed(input) - with returning::scanner[Char, PipelineResult[Program]] + with returning::peeking[Char, PipelineResult[Program]] with scanWithPos with lexer parseAndDesugar() @@ -45,7 +45,7 @@ def runParsing(input: String) : PipelineResult[Program] = { def runParsingFile(path: String) : PipelineResult[Program] / Exception[IOError] = { try { with readFileUTF8(path) - with returning::scanner[Char, PipelineResult[Program]] + with returning::peeking[Char, PipelineResult[Program]] with scanWithPos with lexer parseAndDesugar() diff --git a/src/lib/runner/runRepl.effekt b/src/lib/runner/runRepl.effekt index 65bf3ca..099f164 100644 --- a/src/lib/runner/runRepl.effekt +++ b/src/lib/runner/runRepl.effekt @@ -33,7 +33,7 @@ def readInputBlock(): String / REPLConsole = { var isEmpty = true var result = "" - with stringBuffer + with flushableStringBuffer while (reading) { if (isEmpty) { @@ -114,7 +114,7 @@ def startRepl() = { if (evalState.value is VUnit()) { () } else { - do writeLine(evalState.value.show) + do writeLine(helpers::show(evalState.value)) } } diff --git a/src/lib/shared/commonHandlers.effekt b/src/lib/shared/commonHandlers.effekt index d710183..cf4755e 100644 --- a/src/lib/shared/commonHandlers.effekt +++ b/src/lib/shared/commonHandlers.effekt @@ -6,7 +6,7 @@ import src/lib/shared/commonTypes /// executes a block of code at a specific source code position def at[R](p: Position) { block: => R / Positioning }: R / Positioning = { - val old = do getPos() + val old = do commonEffects::getPos() do setPos(p) val res = block() do setPos(old) diff --git a/src/lib/typechecker/handlers.effekt b/src/lib/typechecker/handlers.effekt index 883e8fe..e65e212 100644 --- a/src/lib/typechecker/handlers.effekt +++ b/src/lib/typechecker/handlers.effekt @@ -22,7 +22,7 @@ def handleTypingContext[R](initialContext: Map[String, TypeBinding]) { prog: => context.get(name) match { case Some(binding) => resume(binding) case None() => { - raise(NameError(), "Undefined variable '" ++ name ++ "' at " ++ do getPos().show) + raise(NameError(), "Undefined variable '" ++ name ++ "' at " ++ helpers::show(do commonEffects::getPos())) } } } diff --git a/src/lib/typechecker/typecheck.effekt b/src/lib/typechecker/typecheck.effekt index 9355f4e..fa893f1 100644 --- a/src/lib/typechecker/typecheck.effekt +++ b/src/lib/typechecker/typecheck.effekt @@ -72,7 +72,7 @@ def twoPassTypecheck(prog: Program): Map[String, TypeBinding] / { Exception[Type case TInt() => () case TString() => () case TDouble() => () - case _ => raise(TypeError(), "Addition requires String, Int, or Double, but got " ++ concrete.show ++ " at " ++ pos.show) + case _ => raise(TypeError(), "Addition requires String, Int, or Double, but got " ++ helpers::show(concrete) ++ " at " ++ helpers::show(pos)) } } } @@ -152,7 +152,7 @@ def checkStmt(stmt: Stmt): TypingType / { Typing, Context[TypeBinding], Exceptio with at(pos) val binding = do lookup(name) if (not(binding.isMutable)) { - raise[Unit, TypeError](TypeError(), "Cannot assign to immutable variable '" ++ name ++ "' at " ++ do getPos().show) + raise[Unit, TypeError](TypeError(), "Cannot assign to immutable variable '" ++ name ++ "' at " ++ helpers::show(do commonEffects::getPos())) } do equate(binding.tpe, checkExpr(value), pos) TUnit() @@ -192,14 +192,14 @@ def checkStmt(stmt: Stmt): TypingType / { Typing, Context[TypeBinding], Exceptio case BreakStmt(pos) => { if (not(do isInLoop())) { - raise(TypeError(), "'break' is only allowed inside a loop " ++ pos.show) + raise(TypeError(), "'break' is only allowed inside a loop " ++ helpers::show(pos)) } TUnit() } case ContinueStmt(pos) => { if (not(do isInLoop())) { - raise(TypeError(), "'continue' is only allowed inside a loop " ++ pos.show) + raise(TypeError(), "'continue' is only allowed inside a loop " ++ helpers::show(pos)) } TUnit() } @@ -416,7 +416,7 @@ def checkExpr(expr: Expr): TypingType / { Typing, Context[TypeBinding], Position // special case for 'max' and 'min' to ensure all arguments are numeric and of the same type case Variable(name, _) and name == "max" || name == "min" => { if (args.size < 2) { - raise(TypeError(), "'" ++ name ++ "' requires at least two arguments at " ++ pos.show) + raise(TypeError(), "'" ++ name ++ "' requires at least two arguments at " ++ helpers::show(pos)) } val memberType = instantiate(TGen(0)) @@ -463,14 +463,14 @@ def assertIsNumeric(t: TypingType, pos: Position): Unit / { Typing, Positioning, case TInt() => () case TDouble() => () case TVar(_) => do addConstraint(MustBeNumeric(t, pos)) // add a constraint to be checked later - case _ => raise(TypeError(), "Expected numeric type, but got " ++ t.show ++ " at " ++ pos.show) + case _ => raise(TypeError(), "Expected numeric type, but got " ++ helpers::show(t) ++ " at " ++ helpers::show(pos)) } /// validate that a type is numeric (int or double) def validateIsNumeric(t: TypingType, pos: Position): Unit / { Exception[TypeError], Positioning } = t match { case TInt() => () case TDouble() => () - case _ => raise(TypeError(), "Expected numeric type, but got " ++ t.show ++ " at " ++ pos.show) + case _ => raise(TypeError(), "Expected numeric type, but got " ++ helpers::show(t) ++ " at " ++ helpers::show(pos)) } /// translate an optional Type annotation into a TypingType diff --git a/src/lib/typechecker/unification.effekt b/src/lib/typechecker/unification.effekt index 97c73f5..7dffb25 100644 --- a/src/lib/typechecker/unification.effekt +++ b/src/lib/typechecker/unification.effekt @@ -115,7 +115,7 @@ def unify(eqs: List[TypeEquation], subst: Substitution): Substitution / { Except val newEqs = Cons(returnEq, paramsEqs.append(rest)) unify(newEqs, subst) } - case _ => raise(TypeError(), "cannot unify types " ++ lNorm.show ++ " with " ++ rNorm.show ++ " at " ++ do getPos().show) + case _ => raise(TypeError(), "cannot unify types " ++ helpers::show(lNorm) ++ " with " ++ helpers::show(rNorm) ++ " at " ++ helpers::show(do commonEffects::getPos())) } } } @@ -124,7 +124,7 @@ def unify(eqs: List[TypeEquation], subst: Substitution): Substitution / { Except /// helper function to bind a type variable to a typing type during unification def bind(id: Int, t: TypingType, rest: List[TypeEquation], subst: Substitution): Substitution / { Exception[TypeError], Positioning } = { if (occursCheck(id, t)) { - raise(TypeError(), "occurs check failed for variable " ++ id.show ++ " at " ++ do getPos().show) + raise(TypeError(), "occurs check failed for variable " ++ id.show ++ " at " ++ helpers::show(do commonEffects::getPos())) } else { val single = map::singletonGeneric(id, t) val newSubst: Substitution = subst.put(id, t) diff --git a/src/tests/testInterpreter.effekt b/src/tests/testInterpreter.effekt index b4f9d90..6ce911f 100644 --- a/src/tests/testInterpreter.effekt +++ b/src/tests/testInterpreter.effekt @@ -153,7 +153,7 @@ def main() = mainSuite("interpreter") { ) with mockGetPos - with assertThrows[RuntimeError] + with testUtils::assertThrows[RuntimeError] evalProgram([prog]) () } @@ -698,7 +698,7 @@ def main() = mainSuite("interpreter") { ] with mockGetPos - with assertThrows[RuntimeError] + with testUtils::assertThrows[RuntimeError] evalProgram(prog) () } @@ -714,7 +714,7 @@ def main() = mainSuite("interpreter") { ] with mockGetPos - with assertThrows[RuntimeError] + with testUtils::assertThrows[RuntimeError] evalProgram(prog) () } @@ -726,7 +726,7 @@ def main() = mainSuite("interpreter") { ] with mockGetPos - with assertThrows[RuntimeError] + with testUtils::assertThrows[RuntimeError] evalProgram(prog) () } @@ -742,7 +742,7 @@ def main() = mainSuite("interpreter") { ] with mockGetPos - with assertThrows[RuntimeError] + with testUtils::assertThrows[RuntimeError] evalProgram(prog) () } diff --git a/src/tests/testTypechecker.effekt b/src/tests/testTypechecker.effekt index e23782e..23ba812 100644 --- a/src/tests/testTypechecker.effekt +++ b/src/tests/testTypechecker.effekt @@ -75,7 +75,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -106,7 +106,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -120,7 +120,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -167,7 +167,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -204,7 +204,7 @@ def main() = mainSuite("typechecker") { ] with on[TypeError].panic - with assertThrows[NameError] + with testUtils::assertThrows[NameError] with mockGetPos typecheck(prog) @@ -238,7 +238,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -275,7 +275,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -316,7 +316,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -338,7 +338,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -381,7 +381,7 @@ def main() = mainSuite("typechecker") { ] with on[TypeError].panic - with assertThrows[NameError] + with testUtils::assertThrows[NameError] with mockGetPos typecheck(prog) @@ -586,7 +586,7 @@ def main() = mainSuite("typechecker") { ) ] - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with on[NameError].panic with mockGetPos @@ -608,7 +608,7 @@ def main() = mainSuite("typechecker") { ) ] - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with on[NameError].panic with mockGetPos @@ -702,7 +702,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -716,7 +716,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -730,7 +730,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -744,7 +744,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -781,7 +781,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -837,7 +837,7 @@ def main() = mainSuite("typechecker") { ] with on[TypeError].panic - with assertThrows[NameError] + with testUtils::assertThrows[NameError] with mockGetPos typecheck(prog) @@ -873,7 +873,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1005,7 +1005,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1056,7 +1056,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1131,7 +1131,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1145,7 +1145,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1220,7 +1220,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1235,7 +1235,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1250,7 +1250,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1308,7 +1308,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1342,7 +1342,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1525,7 +1525,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1559,7 +1559,7 @@ def main() = mainSuite("typechecker") { ] with on[NameError].panic - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with mockGetPos typecheck(prog) @@ -1614,7 +1614,7 @@ def main() = mainSuite("typechecker") { test("typechecker throws on mixed arithmetic with Int and Double") { val prog = [cExpr(cAdd(cLit(3.0), cLit(2)))] - with assertThrows[TypeError] + with testUtils::assertThrows[TypeError] with on[NameError].panic with mockGetPos From 427555eda170c298451c8ab59afba753278a071d Mon Sep 17 00:00:00 2001 From: Martin Ilgner Date: Mon, 8 Jun 2026 11:03:25 +0200 Subject: [PATCH 3/3] Fix some more --- src/lib/lexer/lexer.effekt | 56 +++++++++++++++--------------- src/tests/helpers/testUtils.effekt | 2 +- src/tests/testLexer.effekt | 48 ++++++++++++------------- src/tests/testParser.effekt | 54 ++++++++++++++-------------- 4 files changed, 80 insertions(+), 80 deletions(-) diff --git a/src/lib/lexer/lexer.effekt b/src/lib/lexer/lexer.effekt index 1d2c729..7247be2 100644 --- a/src/lib/lexer/lexer.effekt +++ b/src/lib/lexer/lexer.effekt @@ -43,7 +43,7 @@ def scanWithPos[R]() { prog: => R / { Scan[Char], Positioning } }: R / Scan[Char // We rethrow the skip to the underlying handler (`do skip()`). // That underlying skip will not trigger another read, since the lower // scanner already buffered the character during peek. - do stream::next() + scanner::skip() // Now we know the character was consumed → update position. updatePos(c) // Clear peek cache @@ -57,7 +57,7 @@ def scanWithPos[R]() { prog: => R / { Scan[Char], Positioning } }: R / Scan[Char val c = do stream::peek() // Then we perform the actual skip (again rethrown) updatePos(c) - do stream::next() + scanner::skip() return c } } @@ -143,7 +143,7 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning // check for fractional part if (next == '.') { // consume '.' - do stream::next() + scanner::skip() // read fractional part as string to avoid precision issues like 123.000001 val fractionalPart = string::collect { @@ -171,7 +171,7 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning def readStringLikeToken(pos: Position, delim: Char): Token / { Scan[Char], stop, Exception[LexerError] } = { // consume opening " - do stream::next() + scanner::skip() // collect string content, handling escape sequences val strValue = try { @@ -183,9 +183,9 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning if (c == delim) { () // end of string literal, stop collecting } else if (c == '\\') { - do stream::next() // consume the \ + scanner::skip() // consume the \ val escaped = do stream::peek() - do stream::next() // consume the char after the \ + scanner::skip() // consume the char after the \ // handle escape sequences escaped match { @@ -202,7 +202,7 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning } loop() } else { - do stream::next() + scanner::skip() do emit(c) // normal char loop() } @@ -215,7 +215,7 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning // expect closing " if (do stream::peek() == delim) { - do stream::next() + scanner::skip() } else { do raise(LexerError(), "Expected " ++ delim.show ++ " at end of string") } @@ -241,83 +241,83 @@ def nextToken(): Token / { Scan[Char], stop, Exception[LexerError], Positioning readStringLikeToken(pos, '\'') } else if (c == '=') { // consume first char - do stream::next() + scanner::skip() // second lookahead to recognize two char tokens val next = do stream::peek() if(next == '=') { - do stream::next() + scanner::skip() Token(Equal(), pos) } else { Token(Assign(), pos) } } else if (c == '!') { // consume '!' and check for '!=' - do stream::next() + scanner::skip() readIf('=') Token(NotEqual(), pos) } else if (c == '<') { - do stream::next() + scanner::skip() val next = do stream::peek() if (next == '=') { - do stream::next() + scanner::skip() Token(LessEqual(), pos) } else { Token(Less(), pos) } } else if (c == '>') { - do stream::next() + scanner::skip() val next = do stream::peek() if (next == '=') { - do stream::next() + scanner::skip() Token(GreaterEqual(), pos) } else { Token(Greater(), pos) } } else if (c == '+') { - do stream::next() + scanner::skip() val next = do stream::peek() if (next == '=') { - do stream::next() + scanner::skip() Token(PlusAssign(), pos) } else { Token(Plus(), pos) } } else if (c == '-') { - do stream::next() + scanner::skip() val next = do stream::peek() if (next == '=') { - do stream::next() + scanner::skip() Token(MinusAssign(), pos) } else if (next == '>') { - do stream::next() + scanner::skip() Token(Arrow(), pos) } else { Token(Minus(), pos) } } else if (c == '*') { - do stream::next() + scanner::skip() Token(Mult(), pos) } else if (c == '/') { - do stream::next() + scanner::skip() Token(Div(), pos) } else if (c == '(') { - do stream::next() + scanner::skip() Token(LParen(), pos) } else if (c == ')') { - do stream::next() + scanner::skip() Token(RParen(), pos) } else if (c == '{') { - do stream::next() + scanner::skip() Token(LBrace(), pos) } else if (c == '}') { - do stream::next() + scanner::skip() Token(RBrace(), pos) } else if (c == ':') { - do stream::next() + scanner::skip() Token(Colon(), pos) } else if (c == ',') { - do stream::next() + scanner::skip() Token(Comma(), pos) } else { do raise(LexerError(), "can not tokenize char: " ++ "'" ++ c.show ++ "'" ++ " at " ++ helpers::show(pos)) diff --git a/src/tests/helpers/testUtils.effekt b/src/tests/helpers/testUtils.effekt index 63fa7d8..e335047 100644 --- a/src/tests/helpers/testUtils.effekt +++ b/src/tests/helpers/testUtils.effekt @@ -9,7 +9,7 @@ def assertNotThrown[E](ex: on[E]){ body: => Unit / Exception[E] }: Unit / Assert def assertNoThrow[E]{ body: => Unit / Exception[E] }: Unit / Assertion = on[E].default{ do assert(false, "Unexpected Exception") } {body} -def assertThrown[E](ex: on[E]){ body: => Unit / Exception[E] }: Unit / Assertion = +def testUtils::assertThrown[E](ex: on[E]){ body: => Unit / Exception[E] }: Unit / Assertion = do assert(ex.default { true } { body(); false }, "Expected Exception, but exited normally") def assertThrows[E]{body: => Unit / Exception[E] }: Unit / Assertion = diff --git a/src/tests/testLexer.effekt b/src/tests/testLexer.effekt index 55fb5dc..26c6fa2 100644 --- a/src/tests/testLexer.effekt +++ b/src/tests/testLexer.effekt @@ -25,14 +25,14 @@ def main() = mainSuite("lexer") { def fullLexerHandler(input: String, assertLexerError: Bool) { prog: => Unit / { Lexer[Token] } } = { if (assertLexerError) { with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos - with on[LexerError].assertThrown + with on[LexerError].testUtils::assertThrown with lexer prog() } else { with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with on[LexerError].panic with lexer @@ -79,7 +79,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -98,7 +98,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -116,7 +116,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -124,14 +124,14 @@ def main() = mainSuite("lexer") { val input = "val x = 2;" with fullLexerHandler(input, true) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } } test("lexer throws LexerError if an identifier starts with a Integer") { val input = "val 1x = 2" with fullLexerHandler(input, true) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } } test("lexer recognizes logical operators (and, or, not)") { @@ -146,7 +146,7 @@ def main() = mainSuite("lexer") { while (iter < inputs.size) { with on[OutOfBounds].panic with fullLexerHandler(inputs.get(iter), false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expectedOutputs.get(iter)) iter = iter + 1 } @@ -177,7 +177,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -198,7 +198,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -215,7 +215,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -237,7 +237,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -256,7 +256,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -286,7 +286,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -343,7 +343,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -362,7 +362,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -377,7 +377,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -392,7 +392,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -411,7 +411,7 @@ def main() = mainSuite("lexer") { ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -419,7 +419,7 @@ def main() = mainSuite("lexer") { val input = "val badString = \"This string never ends..." with fullLexerHandler(input, true) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } } test("lexer recognizes double literals") { @@ -436,7 +436,7 @@ def main() = mainSuite("lexer") { Token(Double(0.001), Position(2, 17)) ] with fullLexerHandler(input, false) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } assertEqual(tokens, expected) } @@ -444,13 +444,13 @@ def main() = mainSuite("lexer") { val input = "val badDouble = 3.14.15" with fullLexerHandler(input, true) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } } test("lexer raises LexerError on double literal with missing fractional part") { val input = "val incomplete = 42." with fullLexerHandler(input, true) - val tokens = collectTokens(Nil()) { do next() } + val tokens = collectTokens(Nil()) { do effects::next() } } } \ No newline at end of file diff --git a/src/tests/testParser.effekt b/src/tests/testParser.effekt index d44908d..4067a5f 100644 --- a/src/tests/testParser.effekt +++ b/src/tests/testParser.effekt @@ -31,7 +31,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -58,7 +58,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -87,7 +87,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -112,7 +112,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -140,7 +140,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -170,7 +170,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -201,7 +201,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -238,7 +238,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -275,7 +275,7 @@ def main() = mainSuite("parser") { while (iter < inputs.size) { with on[OutOfBounds].panic with feed(inputs.get(iter)) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -298,7 +298,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -323,7 +323,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -350,7 +350,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -387,7 +387,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -411,7 +411,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -441,7 +441,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -475,7 +475,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -509,7 +509,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -543,7 +543,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -577,7 +577,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -609,7 +609,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -643,7 +643,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -676,7 +676,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -710,7 +710,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -738,7 +738,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -766,7 +766,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -791,7 +791,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic @@ -816,7 +816,7 @@ def main() = mainSuite("parser") { with on[OutOfBounds].panic with feed(input) - with scanner[Char] + with peeking[Char] with scanWithPos with mockGetPos with on[LexerError].panic