mirror of
				https://github.com/GayPizzaSpecifications/pork.git
				synced 2025-11-04 09:59:39 +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