Skip to content

Commit

Permalink
Also merge chez regex into common
Browse files Browse the repository at this point in the history
  • Loading branch information
b-studios committed Jan 22, 2025
1 parent ece15c7 commit 6edbbe7
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 59 deletions.
8 changes: 3 additions & 5 deletions effekt/js/src/main/scala/effekt/context/VirtualModuleDB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ trait VirtualModuleDB extends ModuleDB { self: Context =>
* used by Namer to resolve FFI includes
*/
override def contentsOf(path: String): Option[String] = {
val f = file(module.source.name).parent / path
if (!f.exists) {
None
} else {
Some(f.read)
val parent = file(module.source.name).parent
(parent :: config.includes().map(file)).collectFirst {
case base if (base / path).exists => (base / path).read
}
}

Expand Down
8 changes: 3 additions & 5 deletions effekt/jvm/src/main/scala/effekt/context/IOModuleDB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ trait IOModuleDB extends ModuleDB { self: Context =>
* used by Namer to resolve FFI includes
*/
override def contentsOf(path: String): Option[String] = {
val includeFile = file(module.source.name).parent / path
if (!includeFile.exists) {
None
} else {
Some(FileSource(includeFile.toString).content)
val parent = file(module.source.name).parent
(parent :: config.includes().map(file)).collectFirst {
case base if (base / path).exists => FileSource((base / path).toString).content
}
}

Expand Down
11 changes: 7 additions & 4 deletions effekt/shared/src/main/scala/effekt/core/vm/Builtin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ lazy val arrays: Builtins = Map(
},
)

lazy val undefined: Builtins = Map(
builtin("effekt::isUndefined[A](A)") {
case Value.Literal(m) :: Nil => Value.Bool(m == null)
},
)

lazy val refs: Builtins = Map(
builtin("ref::ref[T](T)") {
case init :: Nil => Value.Ref(Reference(init))
Expand All @@ -281,9 +287,6 @@ lazy val regexes: Builtins = Map(
builtin("regex::exec(Regex, String)") {
case As.Regex(r) :: As.String(str) :: Nil => Value.Literal(r.findFirstMatchIn(str).orNull)
},
builtin("regex::isDefined(RegexMatch)") {
case As.RegexMatch(m) :: Nil => Value.Bool(m != null)
},
builtin("regex::matched(RegexMatch)") {
case As.RegexMatch(m) :: Nil => Value.String(m.matched)
},
Expand All @@ -292,7 +295,7 @@ lazy val regexes: Builtins = Map(
},
)

lazy val builtins: Builtins = printing ++ integers ++ doubles ++ booleans ++ strings ++ arrays ++ refs ++ chars ++ regexes
lazy val builtins: Builtins = printing ++ integers ++ doubles ++ booleans ++ strings ++ arrays ++ refs ++ chars ++ regexes ++ undefined

protected object As {
object String {
Expand Down
2 changes: 1 addition & 1 deletion examples/chez/libraries.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import array
import mutable/dict
import ref

import text/regex
import regex
import string

def main() = ()
2 changes: 1 addition & 1 deletion examples/neg/unbound_type.effekt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module examples/pos/lexer

import string
import text/regex
import regex

effect EOS(): Nothing
effect LexerError(msg: String, pos: Position): Nothing
Expand Down
2 changes: 1 addition & 1 deletion examples/pos/simpleparser.effekt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module examples/pos/simpleparser

import string
import text/regex
import regex

effect fail(msg: String): Nothing

Expand Down
31 changes: 0 additions & 31 deletions libraries/chez/common/text/regex.effekt

This file was deleted.

2 changes: 2 additions & 0 deletions libraries/common/effekt.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -667,11 +667,13 @@ extern pure def toInt(n: Byte): Int =
extern pure def undefined[A](): A =
js "undefined"
chez "#f"
vm "effekt::undefined()"

/// Is an FFI value undefined?
extern pure def isUndefined[A](value: A): Bool =
js "(${value} === undefined || ${value} === null)"
chez "(eq? ${value} #f)"
vm "effekt::isUndefined[A](A)"


// Tuples
Expand Down
37 changes: 26 additions & 11 deletions libraries/common/regex.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,59 @@ module regex

import string

extern include chez "text/pregexp.scm"

extern type Regex

record Match(matched: String, index: Int)

extern pure def regex(str: String): Regex =
js "new RegExp(${str})"
chez "(pregexp ${str})"
vm "regex::regex(String)"

def exec(reg: Regex, str: String): Option[Match] = {
val v = reg.unsafeExec(str)
if (v.isDefined)
Some(Match(v.matched, v.index))
else
if (v.isUndefined)
None()
else
Some(Match(v.matched, v.index))
}

extern type RegexMatch
// js: { matched: String, index: Int } | undefined
// vm: scala.util.matching.Regex.Match | null
extern pure def isDefined(r: RegexMatch): Bool =
js "!!${r}"
vm "regex::isDefined(RegexMatch)"

extern pure def matched(r: RegexMatch): String =
js "${r}.matched"
chez "(vector-ref ${r} 0)"
vm "regex::matched(RegexMatch)"

extern pure def index(r: RegexMatch): Int =
js "${r}.index"
chez "(vector-ref ${r} 1)"
vm "regex::index(RegexMatch)"

extern js """
function regex$exec(reg, str) {
var res = reg.exec(str);
if (res === null) { return undefined }
else { return { matched: res[0], index: res.index } }
}
function regex$exec(reg, str) {
var res = reg.exec(str);
if (res === null) { return undefined }
else { return { matched: res[0], index: res.index } }
}
"""

extern chez """
(define regex-exec
(lambda (regex str)
(let* ([positions (pregexp-match-positions regex str)]
[match (pregexp-match regex str)])
(if (and positions match)
(vector (car match) (caar positions))
#f))))
"""

// internals
extern io def unsafeExec(reg: Regex, str: String): RegexMatch =
js "regex$exec(${reg}, ${str})"
chez "(regex-exec ${reg} ${str})"
vm "regex::exec(Regex, String)"

0 comments on commit 6edbbe7

Please sign in to comment.