Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/benchmarks/input_output/number_matrix.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def emitNumbers(n: Int) =
def readDigit(): Int / { Scan[Byte], stop } = {
val byte = do peek()
if (byte.toInt >= 48 && byte.toInt <= 57) {
do skip()
skip()
return (byte.toInt - 48)
} else {
do stop()
Expand All @@ -67,7 +67,7 @@ def readDecimal(): Int / Scan[Byte] = {
def readNumbers(): Unit / { Scan[Byte], emit[Int] } =
loop {
do emit(readDecimal())
do skip()
skip()
}


Expand Down
14 changes: 7 additions & 7 deletions libraries/common/json.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ def readDouble(): Double / { Scan[Char], Exception[WrongFormat]} = {
def exponent(pre: Double): Double / fail = {
try {
if(do peek() == 'e' || do peek() == 'E') {
do skip[Char]()
skip[Char]()
val e = do peek[Char]() match {
case '+' => do skip[Char](); readDecimal()
case '-' => do skip[Char](); neg(readDecimal())
case '+' => skip[Char](); readDecimal()
case '-' => skip[Char](); neg(readDecimal())
case _ => readDecimal()
}
pre * pow(10.0, e)
Expand Down Expand Up @@ -133,9 +133,9 @@ def readQuotedString(): Unit / { Scan[Char], emit[Char], Exception[WrongFormat]
with expect("Unexpected end of input while reading a string")
skipWhitespace()
expect("Expected \"") { must { readIf('"') } }
while(must { read[Char]() } is c and c != '"') {
while(must { do read[Char]() } is c and c != '"') {
c match {
case '\\' => must { read[Char]() } match {
case '\\' => must { do read[Char]() } match {
case '"' => do emit('\"')
case '\\' => do emit('\\')
case '/' => do emit('/')
Expand Down Expand Up @@ -184,7 +184,7 @@ def decodeJsonObject(): Unit / {Scan[Char], JsonObjectBuilder, Exception[WrongFo
skipWhitespace()
first = false
}
must { do skip() }
must { skip() }
}
def decodeJsonList(): Unit / {Scan[Char], JsonBuilder, Exception[WrongFormat]} = {
var first = true
Expand All @@ -197,7 +197,7 @@ def decodeJsonList(): Unit / {Scan[Char], JsonBuilder, Exception[WrongFormat]} =
skipWhitespace()
first = false
}
must { do skip() }
must { skip() }
}

// --------------------------------------------------------------------------------
Expand Down
51 changes: 22 additions & 29 deletions libraries/common/scanner.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,12 @@ module scanner

import stream

interface Scan[A] {
/// Return the next character, not advancing.
/// That is, this does not change what any future calls on the Scanner return.
def peek(): A / stop
/// Advance the Scanner to the next character.
def skip(): Unit / stop
}

effect peek[A](): A / stop

/// Advance the Scanner to the next token, returning it.
def read[A](): A / { Scan[A], stop } = {
val t = do peek()
do skip()
return t
}
effect Scan[A] = {read[A], peek[A]}

def skip[A](): Unit / {read[A], stop} = { do read(); () }


/// Run a scanner by reading from an input stream, discarding its output.
Expand All @@ -29,15 +20,15 @@ def expect(message: String) { scanner: () => Unit / fail }: Unit / Exception[Wro
/// If conversion is successful read the next token, otherwise stop.
def readWhen[A, B] { convert: A => B / fail }: B / { Scan[A], stop } = {
val t = attempt { convert(do peek()) } { do stop() };
do skip();
do read()
return t
}

/// Check that the next token satisfies the predicate and skip and return it when it does.
def readIf[A] { predicate: A => Bool }: A / { Scan[A], stop } = {
val t = do peek()
if (predicate(t)) {
do skip()
do read()
return t
} else {
do stop()
Expand All @@ -51,7 +42,7 @@ def skipIf[A] { predicate: A => Bool }: Unit / { Scan[A], stop } = {

/// Skips the next token but fails instead of stopping.
def mustSkip[A](): Unit / { Scan[A], fail } =
must { do skip() }
must { skip() }

/// Skips the next character but fails if it is not the given one.
def mustSkip(token: Char): Unit / { Scan[Char], fail } =
Expand Down Expand Up @@ -91,19 +82,21 @@ def skipIf(e: Char): Unit / { Scan[Char], stop } =
/// Immediately stops when already at the end.
def until[A, R] { predicate: A => Bool } { scanner: () => R / Scan[A] }: R / { Scan[A], stop } = {
var stopped = false
if (predicate(do peek())) { stopped = true; do skip() }
if (predicate(do peek())) { stopped = true; skip() }
try {
scanner()
} with Scan[A] {
def peek() = resume {
} with peek[A] {
resume {
if (stopped) { do stop() } else { do peek() }
}
def skip() = resume {
} with read[A] {
resume {
if (stopped) { do stop() } else {
do skip()
val t = do read()
boundary {
if (predicate(do peek())) { stopped = true; do skip() }
if (predicate(do peek())) { stopped = true; skip() }
}
return t
}
}
}
Expand Down Expand Up @@ -165,7 +158,7 @@ def readHexadecimal(): Int / { Scan[Char], fail } = {
/// Fails whenn there isn't at least one digit.
def readInteger(): Int / { Scan[Char], fail } =
must { do peek() } match {
case '-' => must { do skip() }; neg(readDecimal())
case '-' => must { skip() }; neg(readDecimal())
case c and isDigit(c) => readDecimal()
case _ => do fail()
}
Expand All @@ -177,8 +170,8 @@ def scanner[A, R] { scanner: () => R / Scan[A] }: R / read[A] = {
var last = None()
try {
scanner()
} with Scan[A] {
def peek() = resume {
} with peek[A] { () =>
resume {
last match {
case None() =>
val t = do read()
Expand All @@ -188,14 +181,14 @@ def scanner[A, R] { scanner: () => R / Scan[A] }: R / read[A] = {
return t
}
}
def skip() = resume {
} with read[A] {
resume {
last match {
case None() =>
val _ = do read()
return ()
do read()
case Some(t) =>
last = None()
return ()
return t
}
}
}
Expand Down
Loading