mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 13:11:32 +00:00
ast: utilize extension functions to prevent larger stack frames from default interface methods
This commit is contained in:
@ -2,14 +2,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
|
||||
import gay.pizza.dough.fs.PlatformFsProvider
|
||||
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)
|
||||
val path by argument("file")
|
||||
|
||||
private val json = Json {
|
||||
prettyPrint = true
|
||||
@ -18,7 +18,7 @@ class AstCommand : CliktCommand(help = "Print AST", name = "ast") {
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
println(json.encodeToString(Node.serializer(), tool.parse()))
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,16 @@ 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.dough.fs.PlatformFsProvider
|
||||
import gay.pizza.pork.ast.NodeCoalescer
|
||||
import gay.pizza.pork.ast.visit
|
||||
import gay.pizza.pork.parser.TokenNodeAttribution
|
||||
|
||||
class AttributeCommand : CliktCommand(help = "Attribute AST", name = "attribute") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
val path by argument("file")
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
val attribution = TokenNodeAttribution()
|
||||
val compilationUnit = tool.parse(attribution)
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import gay.pizza.dough.fs.FsPath
|
||||
import gay.pizza.dough.fs.readString
|
||||
import gay.pizza.pork.frontend.ContentSource
|
||||
import gay.pizza.pork.frontend.FsContentSource
|
||||
import gay.pizza.pork.parser.CharSource
|
||||
import gay.pizza.pork.parser.StringCharSource
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.absolute
|
||||
import kotlin.io.path.readText
|
||||
|
||||
class FileTool(val path: Path) : Tool() {
|
||||
override fun createCharSource(): CharSource = StringCharSource(path.readText())
|
||||
override fun createContentSource(): ContentSource = FsContentSource(path.absolute().parent)
|
||||
override fun rootFilePath(): String = path.fileName.toString()
|
||||
class FileTool(val path: FsPath) : Tool() {
|
||||
override fun createCharSource(): CharSource =
|
||||
StringCharSource(path.readString())
|
||||
override fun createContentSource(): ContentSource =
|
||||
FsContentSource(path.parent!!)
|
||||
override fun rootFilePath(): String = path.fullPathString
|
||||
}
|
||||
|
@ -2,14 +2,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
|
||||
import gay.pizza.dough.fs.PlatformFsProvider
|
||||
import gay.pizza.pork.parser.AnsiHighlightScheme
|
||||
|
||||
class HighlightCommand : CliktCommand(help = "Syntax Highlighter", name = "highlight") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
val path by argument("file")
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
print(tool.highlight(AnsiHighlightScheme()).joinToString(""))
|
||||
}
|
||||
}
|
||||
|
23
tool/src/main/kotlin/gay/pizza/pork/tool/LoopAndMeasure.kt
Normal file
23
tool/src/main/kotlin/gay/pizza/pork/tool/LoopAndMeasure.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package gay.pizza.pork.tool
|
||||
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
fun maybeLoopAndMeasure(loop: Boolean, measure: Boolean, block: () -> Unit) {
|
||||
fun withMaybeMeasurement() {
|
||||
if (measure) {
|
||||
val nanos = measureNanoTime(block)
|
||||
val millis = nanos / 1000000.0
|
||||
System.err.println("time taken: $millis ms (${nanos} ns)")
|
||||
} else {
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
if (loop) {
|
||||
while (true) {
|
||||
withMaybeMeasurement()
|
||||
}
|
||||
} else {
|
||||
withMaybeMeasurement()
|
||||
}
|
||||
}
|
21
tool/src/main/kotlin/gay/pizza/pork/tool/ParseCommand.kt
Normal file
21
tool/src/main/kotlin/gay/pizza/pork/tool/ParseCommand.kt
Normal file
@ -0,0 +1,21 @@
|
||||
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.options.flag
|
||||
import com.github.ajalt.clikt.parameters.options.option
|
||||
import gay.pizza.dough.fs.PlatformFsProvider
|
||||
|
||||
class ParseCommand : CliktCommand(help = "Parse Compilation Unit", name = "parse") {
|
||||
val loop by option("--loop", help = "Loop Parsing").flag()
|
||||
val measure by option("--measure", help = "Measure Time").flag()
|
||||
val path by argument("file")
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
|
||||
maybeLoopAndMeasure(loop, measure) {
|
||||
tool.parse()
|
||||
}
|
||||
}
|
||||
}
|
@ -2,13 +2,13 @@ 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.dough.fs.PlatformFsProvider
|
||||
|
||||
class ReprintCommand : CliktCommand(help = "Reprint Parsed Compilation Unit", name = "reprint") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
val path by argument("file")
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
print(tool.reprint())
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class RootCommand : CliktCommand(
|
||||
HighlightCommand(),
|
||||
TokenizeCommand(),
|
||||
ReprintCommand(),
|
||||
ParseCommand(),
|
||||
AstCommand(),
|
||||
AttributeCommand()
|
||||
)
|
||||
|
@ -4,45 +4,32 @@ import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.options.flag
|
||||
import com.github.ajalt.clikt.parameters.options.option
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
import gay.pizza.dough.fs.PlatformFsProvider
|
||||
import gay.pizza.pork.evaluator.CallableFunction
|
||||
import gay.pizza.pork.evaluator.None
|
||||
import gay.pizza.pork.evaluator.Scope
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class RunCommand : CliktCommand(help = "Run Program", name = "run") {
|
||||
val loop by option("--loop", help = "Loop Program").flag()
|
||||
val measure by option("--measure", help = "Measure Time").flag()
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
val quiet by option("--quiet", help = "Silence Prints").flag()
|
||||
val path by argument("file")
|
||||
|
||||
override fun run() {
|
||||
if (loop) {
|
||||
while (true) {
|
||||
runProgramMaybeMeasure()
|
||||
}
|
||||
} else {
|
||||
runProgramMaybeMeasure()
|
||||
}
|
||||
}
|
||||
|
||||
private fun runProgramMaybeMeasure() {
|
||||
if (measure) {
|
||||
val time = measureTimeMillis {
|
||||
runProgramOnce()
|
||||
}
|
||||
println("time taken: $time ms")
|
||||
} else {
|
||||
runProgramOnce()
|
||||
}
|
||||
}
|
||||
|
||||
private fun runProgramOnce() {
|
||||
val tool = FileTool(path)
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
val scope = Scope()
|
||||
scope.define("println", CallableFunction { arguments ->
|
||||
if (quiet) {
|
||||
return@CallableFunction None
|
||||
}
|
||||
for (argument in arguments.values) {
|
||||
println(argument)
|
||||
}
|
||||
None
|
||||
})
|
||||
tool.evaluate(scope)
|
||||
|
||||
maybeLoopAndMeasure(loop, measure) {
|
||||
tool.evaluate(scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,13 @@ 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.dough.fs.PlatformFsProvider
|
||||
|
||||
class TokenizeCommand : CliktCommand(help = "Tokenize Compilation Unit", name = "tokenize") {
|
||||
val path by argument("file").path(mustExist = true, canBeDir = false)
|
||||
val path by argument("file")
|
||||
|
||||
override fun run() {
|
||||
val tool = FileTool(path)
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
val tokenStream = tool.tokenize()
|
||||
for (token in tokenStream.tokens) {
|
||||
println("${token.start} ${token.type.name} '${sanitize(token.text)}'")
|
||||
|
@ -3,6 +3,7 @@ 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.ast.visit
|
||||
import gay.pizza.pork.evaluator.Arguments
|
||||
import gay.pizza.pork.evaluator.Evaluator
|
||||
import gay.pizza.pork.evaluator.Scope
|
||||
|
Reference in New Issue
Block a user