mirror of
https://github.com/fluencelabs/asmble
synced 2025-04-24 22:32:19 +00:00
Initial commit
This commit is contained in:
commit
87b866c600
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/.gradle
|
||||
/.idea
|
||||
/build
|
||||
/gradle
|
25
build.gradle
Normal file
25
build.gradle
Normal file
@ -0,0 +1,25 @@
|
||||
group 'asmble'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.1.0'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
testCompile group: 'junit', name: 'junit', version: '4.11'
|
||||
}
|
2
settings.gradle
Normal file
2
settings.gradle
Normal file
@ -0,0 +1,2 @@
|
||||
rootProject.name = 'asmble'
|
||||
|
72
src/main/kotlin/asmble/ast/SExpr.kt
Normal file
72
src/main/kotlin/asmble/ast/SExpr.kt
Normal file
@ -0,0 +1,72 @@
|
||||
package asmble.ast
|
||||
|
||||
import asmble.util.Either
|
||||
|
||||
sealed class SExpr {
|
||||
data class Multi(val vals: List<SExpr> = emptyList()) : SExpr()
|
||||
data class Symbol(val contents: String = "", val quoted: Boolean = false) : SExpr()
|
||||
|
||||
companion object {
|
||||
data class ParseError(val charOffset: Int, val msg: String)
|
||||
fun parse(str: CharSequence): Either<Multi, ParseError> {
|
||||
val state = ParseState(str)
|
||||
var ret = emptyList<SExpr>()
|
||||
while (!state.isEof) {
|
||||
ret += state.nextSExpr()
|
||||
if (state.err != null) return Either.Right(ParseError(state.offset, state.err!!))
|
||||
}
|
||||
if (ret.size == 1 && ret[0] is Multi) return Either.Left(ret[0] as Multi)
|
||||
else return Either.Left(Multi(ret))
|
||||
}
|
||||
|
||||
private class ParseState(val str: CharSequence, var offset: Int = 0, var err: String? = null) {
|
||||
fun nextSExpr(): SExpr {
|
||||
skipWhitespace()
|
||||
if (isEof) return Multi()
|
||||
// What type of expr do we have here?
|
||||
when (str[offset]) {
|
||||
'(' -> {
|
||||
offset++
|
||||
var ret = Multi()
|
||||
while (err == null && !isEof && str[offset] != ')') {
|
||||
ret = ret.copy(ret.vals + nextSExpr())
|
||||
}
|
||||
if (err == null) {
|
||||
if (str[offset] == ')') offset++ else err = "EOF when expected ')'"
|
||||
}
|
||||
return ret
|
||||
}
|
||||
'"' -> {
|
||||
offset++
|
||||
// Anything can be escaped (for now)
|
||||
var retStr = ""
|
||||
while (!isEof && str[offset] != '"') {
|
||||
if (str[offset] == '\\') {
|
||||
++offset
|
||||
if (isEof) {
|
||||
err = "EOF when expected char to unescape"
|
||||
break
|
||||
}
|
||||
}
|
||||
retStr += str[offset]
|
||||
offset++
|
||||
}
|
||||
if (err == null && str[offset] != '"') err = "EOF when expected '\"'"
|
||||
return Symbol(retStr, true)
|
||||
}
|
||||
else -> {
|
||||
// Go until next quote or whitespace or parens
|
||||
val origOffset = offset
|
||||
while (!isEof && str[offset] != '(' && str[offset] != ')' &&
|
||||
str[offset] != '"' && !str[offset].isWhitespace()) offset++
|
||||
return Symbol(str.substring(origOffset, offset))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun skipWhitespace() { while (!isEof && str[offset].isWhitespace()) offset++ }
|
||||
|
||||
val isEof: Boolean inline get() = offset >= str.length
|
||||
}
|
||||
}
|
||||
}
|
6
src/main/kotlin/asmble/util/Either.kt
Normal file
6
src/main/kotlin/asmble/util/Either.kt
Normal file
@ -0,0 +1,6 @@
|
||||
package asmble.util
|
||||
|
||||
sealed class Either<out L, out R> {
|
||||
data class Left<out T>(val v: T) : Either<T, Nothing>()
|
||||
data class Right<out T>(val v: T) : Either<Nothing, T>()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user