mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 13:11:32 +00:00
Split out all code into modules.
This commit is contained in:
31
tool/build.gradle.kts
Normal file
31
tool/build.gradle.kts
Normal file
@ -0,0 +1,31 @@
|
||||
plugins {
|
||||
application
|
||||
pork_module
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("org.graalvm.buildtools.native") version "0.9.25"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":ast"))
|
||||
api(project(":parser"))
|
||||
api(project(":frontend"))
|
||||
api(project(":evaluator"))
|
||||
implementation(libs.clikt)
|
||||
implementation(project(":common"))
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set("gay.pizza.pork.tool.MainKt")
|
||||
}
|
||||
|
||||
graalvmNative {
|
||||
binaries {
|
||||
named("main") {
|
||||
imageName.set("pork")
|
||||
mainClass.set("gay.pizza.pork.tool.MainKt")
|
||||
sharedLibrary.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.run.get().outputs.upToDateWhen { false }
|
24
tool/src/main/kotlin/gay/pizza/pork/tool/AstCommand.kt
Normal file
24
tool/src/main/kotlin/gay/pizza/pork/tool/AstCommand.kt
Normal file
@ -0,0 +1,24 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
import gay.pizza.pork.ast.Node
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
class AstCommand : CliktCommand(help = "Print AST", name = "ast") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
|
||||
private val json = Json {
|
||||
prettyPrint = true
|
||||
prettyPrintIndent = " "
|
||||
classDiscriminator = "\$"
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
println(json.encodeToString(Node.serializer(), tool.parse()))
|
||||
}
|
||||
}
|
26
tool/src/main/kotlin/gay/pizza/pork/tool/AttributeCommand.kt
Normal file
26
tool/src/main/kotlin/gay/pizza/pork/tool/AttributeCommand.kt
Normal file
@ -0,0 +1,26 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
import gay.pizza.pork.ast.NodeCoalescer
|
||||
import gay.pizza.pork.parser.TokenNodeAttribution
|
||||
|
||||
class AttributeCommand : CliktCommand(help = "Attribute AST", name = "attribute") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val attribution = TokenNodeAttribution()
|
||||
val compilationUnit = tool.parse(attribution)
|
||||
|
||||
val coalescer = NodeCoalescer { node ->
|
||||
val tokens = attribution.assembleTokens(node)
|
||||
println("node ${node.toString().replace("\n", "^")}")
|
||||
for (token in tokens) {
|
||||
println("token $token")
|
||||
}
|
||||
}
|
||||
coalescer.visit(compilationUnit)
|
||||
}
|
||||
}
|
13
tool/src/main/kotlin/gay/pizza/pork/tool/FileTool.kt
Normal file
13
tool/src/main/kotlin/gay/pizza/pork/tool/FileTool.kt
Normal file
@ -0,0 +1,13 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import gay.pizza.pork.frontend.ContentSource
|
||||
import gay.pizza.pork.frontend.FsContentSource
|
||||
import gay.pizza.pork.parser.StringCharSource
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.readText
|
||||
|
||||
class FileTool(val path: Path) : Tool() {
|
||||
override fun createCharSource(): gay.pizza.pork.parser.CharSource = StringCharSource(path.readText())
|
||||
override fun createContentSource(): ContentSource = FsContentSource(path.parent)
|
||||
override fun rootFilePath(): String = path.fileName.toString()
|
||||
}
|
14
tool/src/main/kotlin/gay/pizza/pork/tool/HighlightCommand.kt
Normal file
14
tool/src/main/kotlin/gay/pizza/pork/tool/HighlightCommand.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
|
||||
class HighlightCommand : CliktCommand(help = "Syntax Highlighter", name = "highlight") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
print(tool.highlight(gay.pizza.pork.parser.AnsiHighlightScheme()).joinToString(""))
|
||||
}
|
||||
}
|
14
tool/src/main/kotlin/gay/pizza/pork/tool/ReprintCommand.kt
Normal file
14
tool/src/main/kotlin/gay/pizza/pork/tool/ReprintCommand.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
|
||||
class ReprintCommand : CliktCommand(help = "Reprint Parsed Compilation Unit", name = "reprint") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
print(tool.reprint())
|
||||
}
|
||||
}
|
22
tool/src/main/kotlin/gay/pizza/pork/tool/RootCommand.kt
Normal file
22
tool/src/main/kotlin/gay/pizza/pork/tool/RootCommand.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.core.subcommands
|
||||
|
||||
class RootCommand : CliktCommand(
|
||||
help = "Pork - The BBQ Language",
|
||||
name = "pork"
|
||||
) {
|
||||
init {
|
||||
subcommands(
|
||||
RunCommand(),
|
||||
HighlightCommand(),
|
||||
TokenizeCommand(),
|
||||
ReprintCommand(),
|
||||
AstCommand(),
|
||||
AttributeCommand()
|
||||
)
|
||||
}
|
||||
|
||||
override fun run() {}
|
||||
}
|
22
tool/src/main/kotlin/gay/pizza/pork/tool/RunCommand.kt
Normal file
22
tool/src/main/kotlin/gay/pizza/pork/tool/RunCommand.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
import gay.pizza.pork.evaluator.CallableFunction
|
||||
import gay.pizza.pork.evaluator.Scope
|
||||
|
||||
class RunCommand : CliktCommand(help = "Run Program", name = "run") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val scope = Scope()
|
||||
scope.define("println", CallableFunction { arguments ->
|
||||
for (argument in arguments.values) {
|
||||
println(argument)
|
||||
}
|
||||
})
|
||||
tool.evaluate(scope)
|
||||
}
|
||||
}
|
22
tool/src/main/kotlin/gay/pizza/pork/tool/TokenizeCommand.kt
Normal file
22
tool/src/main/kotlin/gay/pizza/pork/tool/TokenizeCommand.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
|
||||
class TokenizeCommand : CliktCommand(help = "Tokenize Compilation Unit", name = "tokenize") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val tokenStream = tool.tokenize()
|
||||
for (token in tokenStream.tokens) {
|
||||
println("${token.start} ${token.type.name} '${sanitize(token.text)}'")
|
||||
}
|
||||
}
|
||||
|
||||
private fun sanitize(input: String): String =
|
||||
input
|
||||
.replace("\n", "\\n")
|
||||
.replace("\r", "\\r")
|
||||
}
|
38
tool/src/main/kotlin/gay/pizza/pork/tool/Tool.kt
Normal file
38
tool/src/main/kotlin/gay/pizza/pork/tool/Tool.kt
Normal file
@ -0,0 +1,38 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import gay.pizza.pork.ast.NodeVisitor
|
||||
import gay.pizza.pork.parser.Printer
|
||||
import gay.pizza.pork.ast.CompilationUnit
|
||||
import gay.pizza.pork.evaluator.Arguments
|
||||
import gay.pizza.pork.evaluator.Evaluator
|
||||
import gay.pizza.pork.evaluator.Scope
|
||||
import gay.pizza.pork.frontend.ContentSource
|
||||
import gay.pizza.pork.frontend.World
|
||||
import gay.pizza.pork.parser.*
|
||||
|
||||
abstract class Tool {
|
||||
abstract fun createCharSource(): CharSource
|
||||
abstract fun createContentSource(): ContentSource
|
||||
abstract fun rootFilePath(): String
|
||||
|
||||
fun tokenize(): TokenStream =
|
||||
Tokenizer(createCharSource()).tokenize()
|
||||
|
||||
fun parse(attribution: NodeAttribution = DiscardNodeAttribution): CompilationUnit =
|
||||
Parser(TokenStreamSource(tokenize()), attribution).readCompilationUnit()
|
||||
|
||||
fun highlight(scheme: HighlightScheme): List<Highlight> =
|
||||
Highlighter(scheme).highlight(tokenize())
|
||||
|
||||
fun reprint(): String = buildString { visit(Printer(this)) }
|
||||
|
||||
fun <T> visit(visitor: NodeVisitor<T>): T = visitor.visit(parse())
|
||||
|
||||
fun evaluate(scope: Scope) {
|
||||
val contentSource = createContentSource()
|
||||
val world = World(contentSource)
|
||||
val evaluator = Evaluator(world, scope)
|
||||
val resultingScope = evaluator.evaluate(rootFilePath())
|
||||
resultingScope.call("main", Arguments(emptyList()))
|
||||
}
|
||||
}
|
3
tool/src/main/kotlin/gay/pizza/pork/tool/main.kt
Normal file
3
tool/src/main/kotlin/gay/pizza/pork/tool/main.kt
Normal file
@ -0,0 +1,3 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
fun main(args: Array<String>) = RootCommand().main(args)
|
Reference in New Issue
Block a user