mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 12:50:55 +00:00
language: prelude and internal functions, and varargs support
This commit is contained in:
parent
1cfb197a7f
commit
e8c984f2dc
10
README.md
10
README.md
@ -5,11 +5,11 @@ A work-in-progress programming language.
|
||||
```pork
|
||||
/* fibonacci sequence */
|
||||
func fib(n) {
|
||||
if n == 0
|
||||
then 0
|
||||
else if n == 1
|
||||
then 1
|
||||
else fib(n - 1) + fib(n - 2)
|
||||
if n < 2 {
|
||||
n
|
||||
} else {
|
||||
fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -117,6 +117,12 @@ types:
|
||||
type: Symbol
|
||||
- name: arguments
|
||||
type: List<Expression>
|
||||
ArgumentSpec:
|
||||
values:
|
||||
- name: symbol
|
||||
type: Symbol
|
||||
- name: multiple
|
||||
type: Boolean
|
||||
FunctionDefinition:
|
||||
parent: Definition
|
||||
values:
|
||||
@ -125,7 +131,7 @@ types:
|
||||
- name: symbol
|
||||
type: Symbol
|
||||
- name: arguments
|
||||
type: List<Symbol>
|
||||
type: List<ArgumentSpec>
|
||||
- name: block
|
||||
type: Block?
|
||||
- name: native
|
||||
|
@ -14,6 +14,7 @@ digraph A {
|
||||
type_InfixOperation [shape=box,label="InfixOperation"]
|
||||
type_BooleanLiteral [shape=box,label="BooleanLiteral"]
|
||||
type_FunctionCall [shape=box,label="FunctionCall"]
|
||||
type_ArgumentSpec [shape=box,label="ArgumentSpec"]
|
||||
type_FunctionDefinition [shape=box,label="FunctionDefinition"]
|
||||
type_If [shape=box,label="If"]
|
||||
type_ImportDeclaration [shape=box,label="ImportDeclaration"]
|
||||
@ -70,8 +71,10 @@ digraph A {
|
||||
type_InfixOperation -> type_InfixOperator [style=dotted]
|
||||
type_FunctionCall -> type_Symbol [style=dotted]
|
||||
type_FunctionCall -> type_Expression [style=dotted]
|
||||
type_ArgumentSpec -> type_Symbol [style=dotted]
|
||||
type_FunctionDefinition -> type_DefinitionModifiers [style=dotted]
|
||||
type_FunctionDefinition -> type_Symbol [style=dotted]
|
||||
type_FunctionDefinition -> type_ArgumentSpec [style=dotted]
|
||||
type_FunctionDefinition -> type_Block [style=dotted]
|
||||
type_FunctionDefinition -> type_Native [style=dotted]
|
||||
type_If -> type_Expression [style=dotted]
|
||||
|
9
ast/src/main/kotlin/gay/pizza/pork/ast/ArgumentSpec.kt
Normal file
9
ast/src/main/kotlin/gay/pizza/pork/ast/ArgumentSpec.kt
Normal file
@ -0,0 +1,9 @@
|
||||
// GENERATED CODE FROM PORK AST CODEGEN
|
||||
package gay.pizza.pork.ast
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@SerialName("argumentSpec")
|
||||
class ArgumentSpec(var symbol: Symbol, var multiple: Boolean)
|
@ -6,11 +6,11 @@ import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@SerialName("functionDefinition")
|
||||
class FunctionDefinition(override val modifiers: DefinitionModifiers, override val symbol: Symbol, val arguments: List<Symbol>, val block: Block?, val native: Native?) : Definition() {
|
||||
class FunctionDefinition(override val modifiers: DefinitionModifiers, override val symbol: Symbol, val arguments: List<ArgumentSpec>, val block: Block?, val native: Native?) : Definition() {
|
||||
override val type: NodeType = NodeType.FunctionDefinition
|
||||
|
||||
override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
|
||||
visitor.visitAll(listOf(symbol), arguments, listOf(block), listOf(native))
|
||||
visitor.visitAll(listOf(symbol), listOf(block), listOf(native))
|
||||
|
||||
override fun <T> visit(visitor: NodeVisitor<T>): T =
|
||||
visitor.visitFunctionDefinition(this)
|
||||
|
@ -1,9 +1,6 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.CompilationUnit
|
||||
import gay.pizza.pork.ast.Definition
|
||||
import gay.pizza.pork.ast.FunctionDefinition
|
||||
import gay.pizza.pork.ast.ImportDeclaration
|
||||
import gay.pizza.pork.ast.*
|
||||
import gay.pizza.pork.frontend.ImportLocator
|
||||
|
||||
class CompilationUnitContext(
|
||||
@ -45,6 +42,7 @@ class CompilationUnitContext(
|
||||
}
|
||||
|
||||
private fun processAllImports() {
|
||||
processPreludeImport()
|
||||
val imports = compilationUnit.declarations.filterIsInstance<ImportDeclaration>()
|
||||
for (import in imports) {
|
||||
processImport(import)
|
||||
@ -57,4 +55,18 @@ class CompilationUnitContext(
|
||||
val evaluationContext = evaluator.context(importLocator)
|
||||
internalScope.inherit(evaluationContext.externalScope)
|
||||
}
|
||||
|
||||
private fun processPreludeImport() {
|
||||
processImport(preludeImport)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val preludeImport = ImportDeclaration(
|
||||
Symbol("std"),
|
||||
listOf(
|
||||
Symbol("lang"),
|
||||
Symbol("prelude")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -119,8 +119,8 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||
subtract = { a, b -> a - b },
|
||||
multiply = { a, b -> a * b },
|
||||
divide = { a, b -> a / b },
|
||||
euclideanModulo = { _, _ -> throw RuntimeException("Can't perform integer modulo between floating point types") },
|
||||
remainder = { _, _ -> throw RuntimeException("Can't perform integer remainder between floating point types") },
|
||||
euclideanModulo = { _, _ -> floatingPointTypeError("integer modulo") },
|
||||
remainder = { _, _ -> floatingPointTypeError("integer remainder") },
|
||||
lesser = { a, b -> a < b },
|
||||
greater = { a, b -> a > b },
|
||||
lesserEqual = { a, b -> a <= b },
|
||||
@ -138,8 +138,8 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||
subtract = { a, b -> a - b },
|
||||
multiply = { a, b -> a * b },
|
||||
divide = { a, b -> a / b },
|
||||
euclideanModulo = { _, _ -> throw RuntimeException("Can't perform integer modulo between floating point types") },
|
||||
remainder = { _, _ -> throw RuntimeException("Can't perform integer remainder between floating point types") },
|
||||
euclideanModulo = { _, _ -> floatingPointTypeError("integer modulo") },
|
||||
remainder = { _, _ -> floatingPointTypeError("integer remainder") },
|
||||
lesser = { a, b -> a < b },
|
||||
greater = { a, b -> a > b },
|
||||
lesserEqual = { a, b -> a <= b },
|
||||
@ -228,31 +228,19 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||
}
|
||||
|
||||
override fun visitFunctionDefinition(node: FunctionDefinition): Any {
|
||||
throw RuntimeException(
|
||||
"Function declarations cannot be visited in an EvaluationVisitor. " +
|
||||
"Utilize a FunctionContext."
|
||||
)
|
||||
topLevelUsedError("FunctionDefinition", "FunctionContext")
|
||||
}
|
||||
|
||||
override fun visitImportDeclaration(node: ImportDeclaration): Any {
|
||||
throw RuntimeException(
|
||||
"Import declarations cannot be visited in an EvaluationVisitor. " +
|
||||
"Utilize an CompilationUnitContext."
|
||||
)
|
||||
topLevelUsedError("ImportDeclaration", "CompilationUnitContext")
|
||||
}
|
||||
|
||||
override fun visitCompilationUnit(node: CompilationUnit): Any {
|
||||
throw RuntimeException(
|
||||
"Compilation units cannot be visited in an EvaluationVisitor. " +
|
||||
"Utilize an CompilationUnitContext."
|
||||
)
|
||||
topLevelUsedError("CompilationUnit", "CompilationUnitContext")
|
||||
}
|
||||
|
||||
override fun visitNative(node: Native): Any {
|
||||
throw RuntimeException(
|
||||
"Native definition cannot be visited in an EvaluationVisitor. " +
|
||||
"Utilize an FunctionContext."
|
||||
)
|
||||
topLevelUsedError("Native", "FunctionContext")
|
||||
}
|
||||
|
||||
override fun visitContinue(node: Continue): Any = ContinueMarker
|
||||
@ -266,6 +254,17 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||
}
|
||||
}
|
||||
|
||||
private fun floatingPointTypeError(operation: String): Nothing {
|
||||
throw RuntimeException("Can't perform $operation between floating point types")
|
||||
}
|
||||
|
||||
private fun topLevelUsedError(name: String, alternative: String): Nothing {
|
||||
throw RuntimeException(
|
||||
"$name cannot be visited in an EvaluationVisitor. " +
|
||||
"Utilize an $alternative instead."
|
||||
)
|
||||
}
|
||||
|
||||
private object BreakMarker : RuntimeException("Break Marker")
|
||||
private object ContinueMarker: RuntimeException("Continue Marker")
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import gay.pizza.pork.frontend.World
|
||||
|
||||
class Evaluator(val world: World, val scope: Scope) {
|
||||
private val contexts = mutableMapOf<String, CompilationUnitContext>()
|
||||
private val nativeFunctionProviders = mutableMapOf<String, NativeFunctionProvider>()
|
||||
private val nativeProviders = mutableMapOf<String, NativeProvider>()
|
||||
|
||||
fun evaluate(locator: ImportLocator): Scope =
|
||||
context(locator).externalScope
|
||||
@ -20,12 +20,12 @@ class Evaluator(val world: World, val scope: Scope) {
|
||||
return context
|
||||
}
|
||||
|
||||
fun nativeFunctionProvider(form: String): NativeFunctionProvider {
|
||||
return nativeFunctionProviders[form] ?:
|
||||
fun nativeFunctionProvider(form: String): NativeProvider {
|
||||
return nativeProviders[form] ?:
|
||||
throw RuntimeException("Unknown native function form: $form")
|
||||
}
|
||||
|
||||
fun addNativeFunctionProvider(form: String, nativeFunctionProvider: NativeFunctionProvider) {
|
||||
nativeFunctionProviders[form] = nativeFunctionProvider
|
||||
fun addNativeProvider(form: String, nativeProvider: NativeProvider) {
|
||||
nativeProviders[form] = nativeProvider
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,14 @@ class FunctionContext(val compilationUnitContext: CompilationUnitContext, val no
|
||||
}
|
||||
|
||||
val scope = compilationUnitContext.internalScope.fork()
|
||||
for ((index, argumentSymbol) in node.arguments.withIndex()) {
|
||||
scope.define(argumentSymbol.id, arguments.values[index])
|
||||
for ((index, spec) in node.arguments.withIndex()) {
|
||||
if (spec.multiple) {
|
||||
val list = arguments.values.subList(index, arguments.values.size - 1)
|
||||
scope.define(spec.symbol.id, list)
|
||||
break
|
||||
} else {
|
||||
scope.define(spec.symbol.id, arguments.values[index])
|
||||
}
|
||||
}
|
||||
|
||||
if (node.block == null) {
|
||||
|
@ -0,0 +1,23 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
|
||||
private val functions = mutableMapOf(
|
||||
"println" to CallableFunction(::printLine)
|
||||
)
|
||||
|
||||
override fun provideNativeFunction(definition: String): CallableFunction {
|
||||
return functions[definition] ?: throw RuntimeException("Unknown Internal Function: $definition")
|
||||
}
|
||||
|
||||
private fun printLine(arguments: Arguments): Any {
|
||||
if (quiet) {
|
||||
return None
|
||||
}
|
||||
when (arguments.values.count()) {
|
||||
0 -> println()
|
||||
1 -> println(arguments.values[0])
|
||||
else -> println(arguments.values.joinToString(" "))
|
||||
}
|
||||
return None
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
interface NativeFunctionProvider {
|
||||
interface NativeProvider {
|
||||
fun provideNativeFunction(definition: String): CallableFunction
|
||||
}
|
@ -1,17 +1,13 @@
|
||||
/* fibonacci sequence */
|
||||
func fib(n) {
|
||||
if n == 0 {
|
||||
0
|
||||
if n < 2 {
|
||||
n
|
||||
} else {
|
||||
if n == 1 {
|
||||
1
|
||||
} else {
|
||||
fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
}
|
||||
|
||||
export func main() {
|
||||
let result = fib(20)
|
||||
let result = fib(30)
|
||||
println(result)
|
||||
}
|
||||
|
@ -1,11 +1,6 @@
|
||||
package gay.pizza.pork.ffi
|
||||
|
||||
import gay.pizza.pork.ast.CompilationUnit
|
||||
import gay.pizza.pork.ast.DefinitionModifiers
|
||||
import gay.pizza.pork.ast.FunctionDefinition
|
||||
import gay.pizza.pork.ast.Native
|
||||
import gay.pizza.pork.ast.StringLiteral
|
||||
import gay.pizza.pork.ast.Symbol
|
||||
import gay.pizza.pork.ast.*
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Modifier
|
||||
import java.lang.reflect.Parameter
|
||||
@ -149,7 +144,12 @@ class JavaAutogen(val javaClass: Class<*>) {
|
||||
FunctionDefinition(
|
||||
modifiers = DefinitionModifiers(true),
|
||||
symbol = Symbol("${prefix}_${name}"),
|
||||
arguments = parameterNames.map { Symbol(it) },
|
||||
arguments = parameterNames.map {
|
||||
ArgumentSpec(
|
||||
symbol = Symbol(it),
|
||||
multiple = false
|
||||
)
|
||||
},
|
||||
native = asNative(functionDefinition),
|
||||
block = null
|
||||
)
|
||||
|
@ -1,12 +1,12 @@
|
||||
package gay.pizza.pork.ffi
|
||||
|
||||
import gay.pizza.pork.evaluator.CallableFunction
|
||||
import gay.pizza.pork.evaluator.NativeFunctionProvider
|
||||
import gay.pizza.pork.evaluator.NativeProvider
|
||||
import gay.pizza.pork.evaluator.None
|
||||
import java.lang.invoke.MethodHandles
|
||||
import java.lang.invoke.MethodType
|
||||
|
||||
class JavaNativeProvider : NativeFunctionProvider {
|
||||
class JavaNativeProvider : NativeProvider {
|
||||
private val lookup = MethodHandles.lookup()
|
||||
|
||||
override fun provideNativeFunction(definition: String): CallableFunction {
|
||||
|
@ -2,9 +2,9 @@ package gay.pizza.pork.ffi
|
||||
|
||||
import com.sun.jna.Function
|
||||
import gay.pizza.pork.evaluator.CallableFunction
|
||||
import gay.pizza.pork.evaluator.NativeFunctionProvider
|
||||
import gay.pizza.pork.evaluator.NativeProvider
|
||||
|
||||
class JnaNativeProvider : NativeFunctionProvider {
|
||||
class JnaNativeProvider : NativeProvider {
|
||||
override fun provideNativeFunction(definition: String): CallableFunction {
|
||||
val functionDefinition = FfiFunctionDefinition.parse(definition)
|
||||
val function = Function.getFunction(functionDefinition.library, functionDefinition.function)
|
||||
|
@ -217,7 +217,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
||||
private fun readImportDeclaration(): ImportDeclaration = within {
|
||||
expect(TokenType.Import)
|
||||
val form = readSymbolRaw()
|
||||
val components = oneAndContinuedBy(TokenType.Period) { readSymbolRaw() }
|
||||
val components = oneAndContinuedBy(TokenType.Dot) { readSymbolRaw() }
|
||||
ImportDeclaration(form, components)
|
||||
}
|
||||
|
||||
@ -237,7 +237,12 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
||||
val name = readSymbolRaw()
|
||||
expect(TokenType.LeftParentheses)
|
||||
val arguments = collect(TokenType.RightParentheses, TokenType.Comma) {
|
||||
readSymbolRaw()
|
||||
val symbol = readSymbolRaw()
|
||||
var multiple: Boolean = false
|
||||
if (next(TokenType.DotDotDot)) {
|
||||
multiple = true
|
||||
}
|
||||
ArgumentSpec(symbol, multiple)
|
||||
}
|
||||
expect(TokenType.RightParentheses)
|
||||
|
||||
|
@ -155,7 +155,10 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
|
||||
visit(node.symbol)
|
||||
append("(")
|
||||
for ((index, argument) in node.arguments.withIndex()) {
|
||||
visit(argument)
|
||||
visit(argument.symbol)
|
||||
if (argument.multiple) {
|
||||
append("...")
|
||||
}
|
||||
if (index + 1 != node.arguments.size) {
|
||||
append(", ")
|
||||
}
|
||||
|
@ -30,23 +30,25 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
||||
LeftParentheses(SingleChar('(')),
|
||||
RightParentheses(SingleChar(')')),
|
||||
Negation(SingleChar('!'), Promotion('=', Inequality), OperatorFamily),
|
||||
Mod(Keyword("mod"), OperatorFamily),
|
||||
Rem(Keyword("rem"), OperatorFamily),
|
||||
Mod(ManyChars("mod"), OperatorFamily),
|
||||
Rem(ManyChars("rem"), OperatorFamily),
|
||||
Comma(SingleChar(',')),
|
||||
Period(SingleChar('.')),
|
||||
False(Keyword("false"), KeywordFamily),
|
||||
True(Keyword("true"), KeywordFamily),
|
||||
If(Keyword("if"), KeywordFamily),
|
||||
Else(Keyword("else"), KeywordFamily),
|
||||
While(Keyword("while"), KeywordFamily),
|
||||
Continue(Keyword("continue"), KeywordFamily),
|
||||
Break(Keyword("break"), KeywordFamily),
|
||||
Import(Keyword("import"), KeywordFamily),
|
||||
Export(Keyword("export"), KeywordFamily),
|
||||
Func(Keyword("func"), KeywordFamily),
|
||||
Native(Keyword("native"), KeywordFamily),
|
||||
Let(Keyword("let"), KeywordFamily),
|
||||
Var(Keyword("var"), KeywordFamily),
|
||||
DotDotDot(ManyChars("...")),
|
||||
DotDot(ManyChars(".."), Promotion('.', DotDotDot)),
|
||||
Dot(SingleChar('.'), Promotion('.', DotDot)),
|
||||
False(ManyChars("false"), KeywordFamily),
|
||||
True(ManyChars("true"), KeywordFamily),
|
||||
If(ManyChars("if"), KeywordFamily),
|
||||
Else(ManyChars("else"), KeywordFamily),
|
||||
While(ManyChars("while"), KeywordFamily),
|
||||
Continue(ManyChars("continue"), KeywordFamily),
|
||||
Break(ManyChars("break"), KeywordFamily),
|
||||
Import(ManyChars("import"), KeywordFamily),
|
||||
Export(ManyChars("export"), KeywordFamily),
|
||||
Func(ManyChars("func"), KeywordFamily),
|
||||
Native(ManyChars("native"), KeywordFamily),
|
||||
Let(ManyChars("let"), KeywordFamily),
|
||||
Var(ManyChars("var"), KeywordFamily),
|
||||
Whitespace(CharConsumer { it == ' ' || it == '\r' || it == '\n' || it == '\t' }),
|
||||
BlockComment(CommentFamily),
|
||||
LineComment(CommentFamily),
|
||||
@ -54,8 +56,8 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
||||
|
||||
val promotions: List<Promotion> =
|
||||
properties.filterIsInstance<Promotion>()
|
||||
val keyword: Keyword? =
|
||||
properties.filterIsInstance<Keyword>().singleOrNull()
|
||||
val manyChars: ManyChars? =
|
||||
properties.filterIsInstance<ManyChars>().singleOrNull()
|
||||
val singleChar: SingleChar? =
|
||||
properties.filterIsInstance<SingleChar>().singleOrNull()
|
||||
val family: TokenFamily =
|
||||
@ -67,7 +69,7 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
||||
properties.filterIsInstance<TokenUpgrader>().singleOrNull()
|
||||
|
||||
companion object {
|
||||
val Keywords = entries.filter { item -> item.keyword != null }
|
||||
val ManyChars = entries.filter { item -> item.manyChars != null }
|
||||
val SingleChars = entries.filter { item -> item.singleChar != null }
|
||||
val CharConsumers = entries.filter { item ->
|
||||
item.charConsumer != null || item.charIndexConsumer != null }
|
||||
|
@ -3,15 +3,15 @@ package gay.pizza.pork.parser
|
||||
interface TokenTypeProperty {
|
||||
class SingleChar(val char: Char) : TokenTypeProperty
|
||||
class Promotion(val nextChar: Char, val type: TokenType) : TokenTypeProperty
|
||||
class Keyword(val text: String) : TokenTypeProperty
|
||||
class ManyChars(val text: String) : TokenTypeProperty
|
||||
class CharConsumer(val isValid: (Char) -> Boolean) : TokenTypeProperty
|
||||
class CharIndexConsumer(val isValid: (Char, Int) -> Boolean) : TokenTypeProperty
|
||||
open class TokenUpgrader(val maybeUpgrade: (Token) -> Token?) : TokenTypeProperty
|
||||
|
||||
object KeywordUpgrader : TokenUpgrader({ token ->
|
||||
var upgraded: Token? = null
|
||||
for (item in TokenType.Keywords) {
|
||||
if (item.keyword != null && token.text == item.keyword.text) {
|
||||
for (item in TokenType.ManyChars) {
|
||||
if (item.manyChars != null && token.text == item.manyChars.text) {
|
||||
upgraded = Token(item, token.start, token.text)
|
||||
break
|
||||
}
|
||||
|
@ -79,13 +79,18 @@ class Tokenizer(val source: CharSource) {
|
||||
|
||||
var type = item
|
||||
var text = itemChar.toString()
|
||||
for (promotion in item.promotions) {
|
||||
if (source.peek() != promotion.nextChar) {
|
||||
continue
|
||||
var promoted = true
|
||||
while (promoted) {
|
||||
promoted = false
|
||||
for (promotion in type.promotions) {
|
||||
if (source.peek() != promotion.nextChar) {
|
||||
continue
|
||||
}
|
||||
val nextChar = source.next()
|
||||
type = promotion.type
|
||||
text += nextChar
|
||||
promoted = true
|
||||
}
|
||||
val nextChar = source.next()
|
||||
type = promotion.type
|
||||
text += nextChar
|
||||
}
|
||||
return Token(type, tokenStart, text)
|
||||
}
|
||||
|
2
stdlib/src/main/pork/lang/prelude.pork
Normal file
2
stdlib/src/main/pork/lang/prelude.pork
Normal file
@ -0,0 +1,2 @@
|
||||
export func println(messages...)
|
||||
native internal "println"
|
@ -1,2 +1,3 @@
|
||||
lang/prelude.pork
|
||||
ffi/malloc.pork
|
||||
numerics/operator.pork
|
||||
|
@ -19,21 +19,10 @@ class RunCommand : CliktCommand(help = "Run Program", name = "run") {
|
||||
override fun run() {
|
||||
val tool = FileTool(PlatformFsProvider.resolve(path))
|
||||
val scope = Scope()
|
||||
scope.define("println", CallableFunction { arguments ->
|
||||
if (quiet) {
|
||||
return@CallableFunction None
|
||||
}
|
||||
when (arguments.values.count()) {
|
||||
0 -> println()
|
||||
1 -> println(arguments.values[0])
|
||||
else -> println(arguments.values.joinToString(" "))
|
||||
}
|
||||
None
|
||||
})
|
||||
|
||||
val main = tool.loadMainFunction(scope, setupEvaluator = {
|
||||
addNativeFunctionProvider("ffi", JnaNativeProvider())
|
||||
addNativeFunctionProvider("java", JavaNativeProvider())
|
||||
addNativeProvider("internal", InternalNativeProvider(quiet = quiet))
|
||||
addNativeProvider("ffi", JnaNativeProvider())
|
||||
addNativeProvider("java", JavaNativeProvider())
|
||||
})
|
||||
|
||||
if (dumpScope) {
|
||||
|
@ -5,6 +5,7 @@ import gay.pizza.pork.ast.NodeVisitor
|
||||
import gay.pizza.pork.ast.visit
|
||||
import gay.pizza.pork.evaluator.CallableFunction
|
||||
import gay.pizza.pork.evaluator.Evaluator
|
||||
import gay.pizza.pork.evaluator.InternalNativeProvider
|
||||
import gay.pizza.pork.evaluator.Scope
|
||||
import gay.pizza.pork.ffi.JavaAutogenContentSource
|
||||
import gay.pizza.pork.frontend.ContentSource
|
||||
|
Loading…
Reference in New Issue
Block a user