mirror of
				https://github.com/GayPizzaSpecifications/pork.git
				synced 2025-11-03 17:39:38 +00:00 
			
		
		
		
	implement native type compilation
This commit is contained in:
		@ -6,5 +6,6 @@ import kotlinx.serialization.Serializable
 | 
				
			|||||||
enum class IrDefinitionType {
 | 
					enum class IrDefinitionType {
 | 
				
			||||||
  Variable,
 | 
					  Variable,
 | 
				
			||||||
  CodeFunction,
 | 
					  CodeFunction,
 | 
				
			||||||
  NativeFunction
 | 
					  NativeFunction,
 | 
				
			||||||
 | 
					  NativeType,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,6 @@ package gay.pizza.pork.bir
 | 
				
			|||||||
import kotlinx.serialization.Serializable
 | 
					import kotlinx.serialization.Serializable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Serializable
 | 
					@Serializable
 | 
				
			||||||
data class IrNativeDefinition(var form: String, var definitions: List<String>) : IrCodeElement() {
 | 
					data class IrNativeDefinition(var kind: IrNativeDefinitionKind, var form: String, var definitions: List<String>) : IrCodeElement() {
 | 
				
			||||||
  override fun crawl(block: (IrElement) -> Unit) {}
 | 
					  override fun crawl(block: (IrElement) -> Unit) {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					package gay.pizza.pork.bir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import kotlinx.serialization.Serializable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Serializable
 | 
				
			||||||
 | 
					enum class IrNativeDefinitionKind {
 | 
				
			||||||
 | 
					  Function,
 | 
				
			||||||
 | 
					  Type
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -13,7 +13,8 @@ enum class Opcode(val id: UByte) {
 | 
				
			|||||||
  UnaryMinus(10u),
 | 
					  UnaryMinus(10u),
 | 
				
			||||||
  BinaryNot(11u),
 | 
					  BinaryNot(11u),
 | 
				
			||||||
  And(20u),
 | 
					  And(20u),
 | 
				
			||||||
  Native(24u),
 | 
					  NativeFunction(24u),
 | 
				
			||||||
 | 
					  NativeType(43u),
 | 
				
			||||||
  Return(10u),
 | 
					  Return(10u),
 | 
				
			||||||
  StoreLocal(16u),
 | 
					  StoreLocal(16u),
 | 
				
			||||||
  LoadLocal(17u),
 | 
					  LoadLocal(17u),
 | 
				
			||||||
 | 
				
			|||||||
@ -308,6 +308,13 @@ class AstIrEmitter(
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitNativeFunctionDescriptor(node: NativeFunctionDescriptor): IrCodeElement = IrNativeDefinition(
 | 
					  override fun visitNativeFunctionDescriptor(node: NativeFunctionDescriptor): IrCodeElement = IrNativeDefinition(
 | 
				
			||||||
 | 
					    kind = IrNativeDefinitionKind.Function,
 | 
				
			||||||
 | 
					    form = node.form.id,
 | 
				
			||||||
 | 
					    definitions = node.definitions.map { it.text }
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitNativeTypeDescriptor(node: NativeTypeDescriptor): IrCodeElement = IrNativeDefinition(
 | 
				
			||||||
 | 
					    kind = IrNativeDefinitionKind.Type,
 | 
				
			||||||
    form = node.form.id,
 | 
					    form = node.form.id,
 | 
				
			||||||
    definitions = node.definitions.map { it.text }
 | 
					    definitions = node.definitions.map { it.text }
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,8 @@ package gay.pizza.pork.compiler
 | 
				
			|||||||
import gay.pizza.pork.ast.gen.FunctionDefinition
 | 
					import gay.pizza.pork.ast.gen.FunctionDefinition
 | 
				
			||||||
import gay.pizza.pork.ast.gen.LetDefinition
 | 
					import gay.pizza.pork.ast.gen.LetDefinition
 | 
				
			||||||
import gay.pizza.pork.ast.gen.NativeFunctionDescriptor
 | 
					import gay.pizza.pork.ast.gen.NativeFunctionDescriptor
 | 
				
			||||||
 | 
					import gay.pizza.pork.ast.gen.NativeTypeDescriptor
 | 
				
			||||||
 | 
					import gay.pizza.pork.ast.gen.TypeDefinition
 | 
				
			||||||
import gay.pizza.pork.ast.gen.visit
 | 
					import gay.pizza.pork.ast.gen.visit
 | 
				
			||||||
import gay.pizza.pork.bir.IrCodeBlock
 | 
					import gay.pizza.pork.bir.IrCodeBlock
 | 
				
			||||||
import gay.pizza.pork.bir.IrDefinition
 | 
					import gay.pizza.pork.bir.IrDefinition
 | 
				
			||||||
@ -36,25 +38,34 @@ class CompilableSymbol(val compilableSlab: CompilableSlab, val scopeSymbol: Scop
 | 
				
			|||||||
      scope = compilableSlab.slab.scope
 | 
					      scope = compilableSlab.slab.scope
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    irCodeEmitter.enterLocalScope()
 | 
					    irCodeEmitter.enterLocalScope()
 | 
				
			||||||
    val what = if (scopeSymbol.definition is FunctionDefinition) {
 | 
					    val what = when (scopeSymbol.definition) {
 | 
				
			||||||
 | 
					      is FunctionDefinition -> {
 | 
				
			||||||
        val functionDefinition = scopeSymbol.definition as FunctionDefinition
 | 
					        val functionDefinition = scopeSymbol.definition as FunctionDefinition
 | 
				
			||||||
        irCodeEmitter.createFunctionArguments(functionDefinition)
 | 
					        irCodeEmitter.createFunctionArguments(functionDefinition)
 | 
				
			||||||
        functionDefinition.block ?: functionDefinition.nativeFunctionDescriptor!!
 | 
					        functionDefinition.block ?: functionDefinition.nativeFunctionDescriptor!!
 | 
				
			||||||
    } else {
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      is TypeDefinition -> {
 | 
				
			||||||
 | 
					        val typeDefinition = scopeSymbol.definition as TypeDefinition
 | 
				
			||||||
 | 
					        typeDefinition.nativeTypeDescriptor!!
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      else -> {
 | 
				
			||||||
        val letDefinition = scopeSymbol.definition as LetDefinition
 | 
					        val letDefinition = scopeSymbol.definition as LetDefinition
 | 
				
			||||||
        letDefinition.value
 | 
					        letDefinition.value
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    val type = if (what is NativeFunctionDescriptor) {
 | 
					    val type = if (what is NativeFunctionDescriptor) {
 | 
				
			||||||
      IrDefinitionType.NativeFunction
 | 
					      IrDefinitionType.NativeFunction
 | 
				
			||||||
 | 
					    } else if (what is NativeTypeDescriptor) {
 | 
				
			||||||
 | 
					      IrDefinitionType.NativeType
 | 
				
			||||||
    } else if (scopeSymbol.definition is LetDefinition) {
 | 
					    } else if (scopeSymbol.definition is LetDefinition) {
 | 
				
			||||||
      IrDefinitionType.Variable
 | 
					      IrDefinitionType.Variable
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      IrDefinitionType.CodeFunction
 | 
					      IrDefinitionType.CodeFunction
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    val irCodeElement = irCodeEmitter.visit(what)
 | 
					    val irCodeElement = irCodeEmitter.visit(what)
 | 
				
			||||||
    val irCodeBlock = if (irCodeElement is IrCodeBlock) {
 | 
					    val irCodeBlock = irCodeElement as? IrCodeBlock ?: IrCodeBlock(listOf(irCodeElement))
 | 
				
			||||||
      irCodeElement
 | 
					 | 
				
			||||||
    } else IrCodeBlock(listOf(irCodeElement))
 | 
					 | 
				
			||||||
    irCodeEmitter.exitLocalScope()
 | 
					    irCodeEmitter.exitLocalScope()
 | 
				
			||||||
    return IrDefinition(
 | 
					    return IrDefinition(
 | 
				
			||||||
      symbol = functionSymbol,
 | 
					      symbol = functionSymbol,
 | 
				
			||||||
 | 
				
			|||||||
@ -233,7 +233,15 @@ class IrStubOpEmitter(val irDefinition: IrDefinition, val code: CodeBuilder) : I
 | 
				
			|||||||
      ConstantTag.NativeDefinition,
 | 
					      ConstantTag.NativeDefinition,
 | 
				
			||||||
      buffer,
 | 
					      buffer,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    code.emit(Opcode.Native, listOf(nativeDefinitionConstant, functionArgumentCount.toUInt()))
 | 
					
 | 
				
			||||||
 | 
					    when (ir.kind) {
 | 
				
			||||||
 | 
					      IrNativeDefinitionKind.Function -> {
 | 
				
			||||||
 | 
					        code.emit(Opcode.NativeFunction, listOf(nativeDefinitionConstant, functionArgumentCount.toUInt()))
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      IrNativeDefinitionKind.Type -> {
 | 
				
			||||||
 | 
					        code.emit(Opcode.NativeType, listOf(nativeDefinitionConstant))
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitIrIndex(ir: IrIndex) {
 | 
					  override fun visitIrIndex(ir: IrIndex) {
 | 
				
			||||||
 | 
				
			|||||||
@ -8,16 +8,35 @@ class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
 | 
				
			|||||||
    "listInitWith" to NativeFunction(::listInitWith)
 | 
					    "listInitWith" to NativeFunction(::listInitWith)
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private val types = mutableMapOf(
 | 
				
			||||||
 | 
					    "int32" to NativeType { Int::class.java },
 | 
				
			||||||
 | 
					    "int64" to NativeType { Long::class.java },
 | 
				
			||||||
 | 
					    "string" to NativeType { String::class.java },
 | 
				
			||||||
 | 
					    "float32" to NativeType { Float::class.java },
 | 
				
			||||||
 | 
					    "float64" to NativeType { Double::class.java },
 | 
				
			||||||
 | 
					    "bool" to NativeType { Boolean::class.java },
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fun add(name: String, function: NativeFunction) {
 | 
					  fun add(name: String, function: NativeFunction) {
 | 
				
			||||||
    functions[name] = function
 | 
					    functions[name] = function
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fun add(name: String, type: NativeType) {
 | 
				
			||||||
 | 
					    types[name] = type
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun provideNativeFunction(definitions: List<String>): NativeFunction {
 | 
					  override fun provideNativeFunction(definitions: List<String>): NativeFunction {
 | 
				
			||||||
    val definition = definitions[0]
 | 
					    val definition = definitions[0]
 | 
				
			||||||
    return functions[definition] ?:
 | 
					    return functions[definition] ?:
 | 
				
			||||||
      throw RuntimeException("Unknown internal function: $definition")
 | 
					      throw RuntimeException("Unknown internal function: $definition")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun provideNativeType(definitions: List<String>): NativeType {
 | 
				
			||||||
 | 
					    val definition = definitions[0]
 | 
				
			||||||
 | 
					    return types[definition] ?:
 | 
				
			||||||
 | 
					      throw RuntimeException("Unknown internal type: $definition")
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private fun printValues(arguments: ArgumentList): Any {
 | 
					  private fun printValues(arguments: ArgumentList): Any {
 | 
				
			||||||
    if (quiet || arguments.isEmpty()) return None
 | 
					    if (quiet || arguments.isEmpty()) return None
 | 
				
			||||||
    print(arguments.at<List<*>>(0).joinToString(" ") { it.toString() })
 | 
					    print(arguments.at<List<*>>(0).joinToString(" ") { it.toString() })
 | 
				
			||||||
 | 
				
			|||||||
@ -2,4 +2,5 @@ package gay.pizza.pork.execution
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
interface NativeProvider {
 | 
					interface NativeProvider {
 | 
				
			||||||
  fun provideNativeFunction(definitions: List<String>): NativeFunction
 | 
					  fun provideNativeFunction(definitions: List<String>): NativeFunction
 | 
				
			||||||
 | 
					  fun provideNativeType(definitions: List<String>): NativeType
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					package gay.pizza.pork.execution
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun interface NativeType {
 | 
				
			||||||
 | 
					  fun value(): Any
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -8,6 +8,7 @@ import gay.pizza.pork.evaluator.*
 | 
				
			|||||||
import gay.pizza.pork.execution.ArgumentList
 | 
					import gay.pizza.pork.execution.ArgumentList
 | 
				
			||||||
import gay.pizza.pork.execution.NativeFunction
 | 
					import gay.pizza.pork.execution.NativeFunction
 | 
				
			||||||
import gay.pizza.pork.execution.NativeProvider
 | 
					import gay.pizza.pork.execution.NativeProvider
 | 
				
			||||||
 | 
					import gay.pizza.pork.execution.NativeType
 | 
				
			||||||
import gay.pizza.pork.execution.None
 | 
					import gay.pizza.pork.execution.None
 | 
				
			||||||
import kotlin.io.path.Path
 | 
					import kotlin.io.path.Path
 | 
				
			||||||
import kotlin.io.path.absolutePathString
 | 
					import kotlin.io.path.absolutePathString
 | 
				
			||||||
@ -231,6 +232,11 @@ class FfiNativeProvider : ExpandedNativeProvider, NativeProvider {
 | 
				
			|||||||
      callable.call(arguments, CallStack())
 | 
					      callable.call(arguments, CallStack())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun provideNativeType(definitions: List<String>): NativeType {
 | 
				
			||||||
 | 
					    throw RuntimeException("Unknown native type")
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  companion object {
 | 
					  companion object {
 | 
				
			||||||
    fun typeConversion(type: FfiType): Type = when (type) {
 | 
					    fun typeConversion(type: FfiType): Type = when (type) {
 | 
				
			||||||
      FfiPrimitiveType.UnsignedByte -> Type.UINT8
 | 
					      FfiPrimitiveType.UnsignedByte -> Type.UINT8
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@ import gay.pizza.pork.evaluator.SlabContext
 | 
				
			|||||||
import gay.pizza.pork.evaluator.ExpandedNativeProvider
 | 
					import gay.pizza.pork.evaluator.ExpandedNativeProvider
 | 
				
			||||||
import gay.pizza.pork.execution.NativeFunction
 | 
					import gay.pizza.pork.execution.NativeFunction
 | 
				
			||||||
import gay.pizza.pork.execution.NativeProvider
 | 
					import gay.pizza.pork.execution.NativeProvider
 | 
				
			||||||
 | 
					import gay.pizza.pork.execution.NativeType
 | 
				
			||||||
import gay.pizza.pork.execution.None
 | 
					import gay.pizza.pork.execution.None
 | 
				
			||||||
import java.lang.invoke.MethodHandles
 | 
					import java.lang.invoke.MethodHandles
 | 
				
			||||||
import java.lang.invoke.MethodType
 | 
					import java.lang.invoke.MethodType
 | 
				
			||||||
@ -68,4 +69,8 @@ class JavaNativeProvider : ExpandedNativeProvider, NativeProvider {
 | 
				
			|||||||
  override fun provideNativeFunction(definitions: List<String>): NativeFunction {
 | 
					  override fun provideNativeFunction(definitions: List<String>): NativeFunction {
 | 
				
			||||||
    throw RuntimeException("Invalid Native Function Usage")
 | 
					    throw RuntimeException("Invalid Native Function Usage")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun provideNativeType(definitions: List<String>): NativeType {
 | 
				
			||||||
 | 
					    throw RuntimeException("Invalid Native Type Usage")
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,9 @@ class ExternalSymbolUsageAnalyzer : FunctionLevelVisitor<Unit>() {
 | 
				
			|||||||
    internalSymbols.removeLast()
 | 
					    internalSymbols.removeLast()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitTypeDefinition(node: TypeDefinition) {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitLetDefinition(node: LetDefinition) {
 | 
					  override fun visitLetDefinition(node: LetDefinition) {
 | 
				
			||||||
    node.value.visit(this)
 | 
					    node.value.visit(this)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -69,7 +69,7 @@ class CompileCommand : CliktCommand("compile") {
 | 
				
			|||||||
          annotation = " ; ${annotations.joinToString(", ") { it.text }}"
 | 
					          annotation = " ; ${annotations.joinToString(", ") { it.text }}"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        print("  ${symbol.offset + index.toUInt()} ${op}${annotation}")
 | 
					        print("  ${symbol.offset + index.toUInt()} ${op}${annotation}")
 | 
				
			||||||
        if (op.code == Opcode.Constant || op.code == Opcode.Native) {
 | 
					        if (op.code == Opcode.Constant || op.code == Opcode.NativeFunction) {
 | 
				
			||||||
          val constant = compiledWorld.constantPool.constants[op.args[0].toInt()]
 | 
					          val constant = compiledWorld.constantPool.constants[op.args[0].toInt()]
 | 
				
			||||||
          val constantString = when (constant.tag) {
 | 
					          val constantString = when (constant.tag) {
 | 
				
			||||||
            ConstantTag.String -> "string = \"" + constant.readAsString() + "\""
 | 
					            ConstantTag.String -> "string = \"" + constant.readAsString() + "\""
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,8 @@ val StandardOpHandlers: List<OpHandler> = listOf(
 | 
				
			|||||||
  CallOpHandler,
 | 
					  CallOpHandler,
 | 
				
			||||||
  ReturnOpHandler,
 | 
					  ReturnOpHandler,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  NativeOpHandler,
 | 
					  NativeFunctionOpHandler,
 | 
				
			||||||
 | 
					  NativeTypeOpHandler,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ScopeInOpHandler,
 | 
					  ScopeInOpHandler,
 | 
				
			||||||
  ScopeOutOpHandler,
 | 
					  ScopeOutOpHandler,
 | 
				
			||||||
 | 
				
			|||||||
@ -2,11 +2,10 @@ package gay.pizza.pork.vm.ops
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import gay.pizza.pork.bytecode.Op
 | 
					import gay.pizza.pork.bytecode.Op
 | 
				
			||||||
import gay.pizza.pork.bytecode.Opcode
 | 
					import gay.pizza.pork.bytecode.Opcode
 | 
				
			||||||
import gay.pizza.pork.execution.None
 | 
					 | 
				
			||||||
import gay.pizza.pork.vm.InternalMachine
 | 
					import gay.pizza.pork.vm.InternalMachine
 | 
				
			||||||
import gay.pizza.pork.vm.OpHandler
 | 
					import gay.pizza.pork.vm.OpHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
object NativeOpHandler : OpHandler(Opcode.Native) {
 | 
					object NativeFunctionOpHandler : OpHandler(Opcode.NativeFunction) {
 | 
				
			||||||
  override fun handle(machine: InternalMachine, op: Op) {
 | 
					  override fun handle(machine: InternalMachine, op: Op) {
 | 
				
			||||||
    val handler = optimize(machine, op)
 | 
					    val handler = optimize(machine, op)
 | 
				
			||||||
    handler.handle(machine, op)
 | 
					    handler.handle(machine, op)
 | 
				
			||||||
@ -17,6 +16,6 @@ object NativeOpHandler : OpHandler(Opcode.Native) {
 | 
				
			|||||||
    val form = nativeDefinition[0]
 | 
					    val form = nativeDefinition[0]
 | 
				
			||||||
    val provider = machine.nativeRegistry.of(form)
 | 
					    val provider = machine.nativeRegistry.of(form)
 | 
				
			||||||
    val function = provider.provideNativeFunction(nativeDefinition.subList(1, nativeDefinition.size))
 | 
					    val function = provider.provideNativeFunction(nativeDefinition.subList(1, nativeDefinition.size))
 | 
				
			||||||
    return OptimizedNativeOpHandler(function)
 | 
					    return OptimizedNativeFunctionOpHandler(function)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					package gay.pizza.pork.vm.ops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import gay.pizza.pork.bytecode.Op
 | 
				
			||||||
 | 
					import gay.pizza.pork.bytecode.Opcode
 | 
				
			||||||
 | 
					import gay.pizza.pork.vm.InternalMachine
 | 
				
			||||||
 | 
					import gay.pizza.pork.vm.OpHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object NativeTypeOpHandler : OpHandler(Opcode.NativeType) {
 | 
				
			||||||
 | 
					  override fun handle(machine: InternalMachine, op: Op) {
 | 
				
			||||||
 | 
					    val handler = optimize(machine, op)
 | 
				
			||||||
 | 
					    handler.handle(machine, op)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun optimize(machine: InternalMachine, op: Op): OpHandler {
 | 
				
			||||||
 | 
					    val nativeDefinition = machine.world.constantPool.read(op.args[0]).readAsNativeDefinition()
 | 
				
			||||||
 | 
					    val form = nativeDefinition[0]
 | 
				
			||||||
 | 
					    val provider = machine.nativeRegistry.of(form)
 | 
				
			||||||
 | 
					    val type = provider.provideNativeType(nativeDefinition.subList(1, nativeDefinition.size))
 | 
				
			||||||
 | 
					    return OptimizedNativeTypeOpHandler(type)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -7,7 +7,7 @@ import gay.pizza.pork.execution.None
 | 
				
			|||||||
import gay.pizza.pork.vm.InternalMachine
 | 
					import gay.pizza.pork.vm.InternalMachine
 | 
				
			||||||
import gay.pizza.pork.vm.OpHandler
 | 
					import gay.pizza.pork.vm.OpHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OptimizedNativeOpHandler(val function: NativeFunction) : OpHandler(Opcode.Native) {
 | 
					class OptimizedNativeFunctionOpHandler(val function: NativeFunction) : OpHandler(Opcode.NativeFunction) {
 | 
				
			||||||
  override fun handle(machine: InternalMachine, op: Op) {
 | 
					  override fun handle(machine: InternalMachine, op: Op) {
 | 
				
			||||||
    val argumentCount = op.args[1]
 | 
					    val argumentCount = op.args[1]
 | 
				
			||||||
    val arguments = mutableListOf<Any>()
 | 
					    val arguments = mutableListOf<Any>()
 | 
				
			||||||
@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					package gay.pizza.pork.vm.ops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import gay.pizza.pork.bytecode.Op
 | 
				
			||||||
 | 
					import gay.pizza.pork.bytecode.Opcode
 | 
				
			||||||
 | 
					import gay.pizza.pork.execution.NativeFunction
 | 
				
			||||||
 | 
					import gay.pizza.pork.execution.NativeType
 | 
				
			||||||
 | 
					import gay.pizza.pork.execution.None
 | 
				
			||||||
 | 
					import gay.pizza.pork.vm.InternalMachine
 | 
				
			||||||
 | 
					import gay.pizza.pork.vm.OpHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OptimizedNativeTypeOpHandler(val type: NativeType) : OpHandler(Opcode.NativeType) {
 | 
				
			||||||
 | 
					  override fun handle(machine: InternalMachine, op: Op) {
 | 
				
			||||||
 | 
					    val result = type.value()
 | 
				
			||||||
 | 
					    machine.push(if (result == Unit) None else result)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user