mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 21:00:56 +00:00
language: add unary plus & minus, post increment & decrement operators, non-newline print builtin. fix block comments
This commit is contained in:
parent
f6d2fc5165
commit
36b574bf5b
@ -181,6 +181,12 @@ types:
|
|||||||
- name: Negate
|
- name: Negate
|
||||||
values:
|
values:
|
||||||
token: "!"
|
token: "!"
|
||||||
|
- name: UnaryPlus
|
||||||
|
values:
|
||||||
|
token: "+"
|
||||||
|
- name: UnaryMinus
|
||||||
|
values:
|
||||||
|
token: "-"
|
||||||
PrefixOperation:
|
PrefixOperation:
|
||||||
parent: Expression
|
parent: Expression
|
||||||
values:
|
values:
|
||||||
@ -188,6 +194,24 @@ types:
|
|||||||
type: PrefixOperator
|
type: PrefixOperator
|
||||||
- name: expression
|
- name: expression
|
||||||
type: Expression
|
type: Expression
|
||||||
|
SuffixOperator:
|
||||||
|
values:
|
||||||
|
- name: token
|
||||||
|
type: String
|
||||||
|
enums:
|
||||||
|
- name: Increment
|
||||||
|
values:
|
||||||
|
token: "++"
|
||||||
|
- name: Decrement
|
||||||
|
values:
|
||||||
|
token: "--"
|
||||||
|
SuffixOperation:
|
||||||
|
parent: Expression
|
||||||
|
values:
|
||||||
|
- name: op
|
||||||
|
type: SuffixOperator
|
||||||
|
- name: reference
|
||||||
|
type: SymbolReference
|
||||||
StringLiteral:
|
StringLiteral:
|
||||||
parent: Expression
|
parent: Expression
|
||||||
values:
|
values:
|
||||||
|
@ -24,6 +24,8 @@ digraph A {
|
|||||||
type_Parentheses [shape=box,label="Parentheses"]
|
type_Parentheses [shape=box,label="Parentheses"]
|
||||||
type_PrefixOperator [shape=box,label="PrefixOperator"]
|
type_PrefixOperator [shape=box,label="PrefixOperator"]
|
||||||
type_PrefixOperation [shape=box,label="PrefixOperation"]
|
type_PrefixOperation [shape=box,label="PrefixOperation"]
|
||||||
|
type_SuffixOperator [shape=box,label="SuffixOperator"]
|
||||||
|
type_SuffixOperation [shape=box,label="SuffixOperation"]
|
||||||
type_StringLiteral [shape=box,label="StringLiteral"]
|
type_StringLiteral [shape=box,label="StringLiteral"]
|
||||||
type_SymbolReference [shape=box,label="SymbolReference"]
|
type_SymbolReference [shape=box,label="SymbolReference"]
|
||||||
type_While [shape=box,label="While"]
|
type_While [shape=box,label="While"]
|
||||||
@ -49,6 +51,7 @@ digraph A {
|
|||||||
type_Expression -> type_ListLiteral
|
type_Expression -> type_ListLiteral
|
||||||
type_Expression -> type_Parentheses
|
type_Expression -> type_Parentheses
|
||||||
type_Expression -> type_PrefixOperation
|
type_Expression -> type_PrefixOperation
|
||||||
|
type_Expression -> type_SuffixOperation
|
||||||
type_Expression -> type_StringLiteral
|
type_Expression -> type_StringLiteral
|
||||||
type_Expression -> type_SymbolReference
|
type_Expression -> type_SymbolReference
|
||||||
type_Expression -> type_While
|
type_Expression -> type_While
|
||||||
@ -84,6 +87,8 @@ digraph A {
|
|||||||
type_Parentheses -> type_Expression [style=dotted]
|
type_Parentheses -> type_Expression [style=dotted]
|
||||||
type_PrefixOperation -> type_PrefixOperator [style=dotted]
|
type_PrefixOperation -> type_PrefixOperator [style=dotted]
|
||||||
type_PrefixOperation -> type_Expression [style=dotted]
|
type_PrefixOperation -> type_Expression [style=dotted]
|
||||||
|
type_SuffixOperation -> type_SuffixOperator [style=dotted]
|
||||||
|
type_SuffixOperation -> type_SymbolReference [style=dotted]
|
||||||
type_SymbolReference -> type_Symbol [style=dotted]
|
type_SymbolReference -> type_Symbol [style=dotted]
|
||||||
type_While -> type_Expression [style=dotted]
|
type_While -> type_Expression [style=dotted]
|
||||||
type_While -> type_Block [style=dotted]
|
type_While -> type_Block [style=dotted]
|
||||||
|
@ -59,6 +59,9 @@ class NodeCoalescer(val handler: (Node) -> Unit) : NodeVisitor<Unit> {
|
|||||||
override fun visitStringLiteral(node: StringLiteral): Unit =
|
override fun visitStringLiteral(node: StringLiteral): Unit =
|
||||||
handle(node)
|
handle(node)
|
||||||
|
|
||||||
|
override fun visitSuffixOperation(node: SuffixOperation): Unit =
|
||||||
|
handle(node)
|
||||||
|
|
||||||
override fun visitSymbol(node: Symbol): Unit =
|
override fun visitSymbol(node: Symbol): Unit =
|
||||||
handle(node)
|
handle(node)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ enum class NodeType(val parent: NodeType? = null) {
|
|||||||
PrefixOperation(Expression),
|
PrefixOperation(Expression),
|
||||||
SetAssignment(Expression),
|
SetAssignment(Expression),
|
||||||
StringLiteral(Expression),
|
StringLiteral(Expression),
|
||||||
|
SuffixOperation(Expression),
|
||||||
Symbol(Node),
|
Symbol(Node),
|
||||||
SymbolReference(Expression),
|
SymbolReference(Expression),
|
||||||
VarAssignment(Expression),
|
VarAssignment(Expression),
|
||||||
|
@ -40,6 +40,8 @@ interface NodeVisitor<T> {
|
|||||||
|
|
||||||
fun visitStringLiteral(node: StringLiteral): T
|
fun visitStringLiteral(node: StringLiteral): T
|
||||||
|
|
||||||
|
fun visitSuffixOperation(node: SuffixOperation): T
|
||||||
|
|
||||||
fun visitSymbol(node: Symbol): T
|
fun visitSymbol(node: Symbol): T
|
||||||
|
|
||||||
fun visitSymbolReference(node: SymbolReference): T
|
fun visitSymbolReference(node: SymbolReference): T
|
||||||
|
@ -20,6 +20,7 @@ fun <T> NodeVisitor<T>.visit(node: Node): T =
|
|||||||
is ListLiteral -> visitListLiteral(node)
|
is ListLiteral -> visitListLiteral(node)
|
||||||
is Parentheses -> visitParentheses(node)
|
is Parentheses -> visitParentheses(node)
|
||||||
is PrefixOperation -> visitPrefixOperation(node)
|
is PrefixOperation -> visitPrefixOperation(node)
|
||||||
|
is SuffixOperation -> visitSuffixOperation(node)
|
||||||
is StringLiteral -> visitStringLiteral(node)
|
is StringLiteral -> visitStringLiteral(node)
|
||||||
is SymbolReference -> visitSymbolReference(node)
|
is SymbolReference -> visitSymbolReference(node)
|
||||||
is While -> visitWhile(node)
|
is While -> visitWhile(node)
|
||||||
|
@ -7,5 +7,7 @@ import kotlinx.serialization.Serializable
|
|||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("prefixOperator")
|
@SerialName("prefixOperator")
|
||||||
enum class PrefixOperator(val token: String) {
|
enum class PrefixOperator(val token: String) {
|
||||||
Negate("!")
|
Negate("!"),
|
||||||
|
UnaryPlus("+"),
|
||||||
|
UnaryMinus("-")
|
||||||
}
|
}
|
||||||
|
29
ast/src/main/kotlin/gay/pizza/pork/ast/SuffixOperation.kt
Normal file
29
ast/src/main/kotlin/gay/pizza/pork/ast/SuffixOperation.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// GENERATED CODE FROM PORK AST CODEGEN
|
||||||
|
package gay.pizza.pork.ast
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("suffixOperation")
|
||||||
|
class SuffixOperation(val op: SuffixOperator, val reference: SymbolReference) : Expression() {
|
||||||
|
override val type: NodeType = NodeType.SuffixOperation
|
||||||
|
|
||||||
|
override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
|
||||||
|
visitor.visitNodes(reference)
|
||||||
|
|
||||||
|
override fun <T> visit(visitor: NodeVisitor<T>): T =
|
||||||
|
visitor.visitSuffixOperation(this)
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other !is SuffixOperation) return false
|
||||||
|
return other.op == op && other.reference == reference
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = op.hashCode()
|
||||||
|
result = 31 * result + reference.hashCode()
|
||||||
|
result = 31 * result + type.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
12
ast/src/main/kotlin/gay/pizza/pork/ast/SuffixOperator.kt
Normal file
12
ast/src/main/kotlin/gay/pizza/pork/ast/SuffixOperator.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// GENERATED CODE FROM PORK AST CODEGEN
|
||||||
|
package gay.pizza.pork.ast
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("suffixOperator")
|
||||||
|
enum class SuffixOperator(val token: String) {
|
||||||
|
Increment("++"),
|
||||||
|
Decrement("--")
|
||||||
|
}
|
@ -71,9 +71,65 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
|||||||
}
|
}
|
||||||
!value
|
!value
|
||||||
}
|
}
|
||||||
|
PrefixOperator.UnaryPlus, PrefixOperator.UnaryMinus -> {
|
||||||
|
if (value !is Number) {
|
||||||
|
throw RuntimeException("Numeric unary '${node.op.token}' illegal on non-numeric type '${value.javaClass.simpleName}'")
|
||||||
|
}
|
||||||
|
unaryNumericOperation(node, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun unaryNumericOperation(node: PrefixOperation, value: Number) = when (value) {
|
||||||
|
is Double -> {
|
||||||
|
unaryNumericOperation(
|
||||||
|
node.op,
|
||||||
|
value,
|
||||||
|
convert = { it.toDouble() },
|
||||||
|
plus = { +it },
|
||||||
|
minus = { -it }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Float -> {
|
||||||
|
unaryNumericOperation(
|
||||||
|
node.op,
|
||||||
|
value,
|
||||||
|
convert = { it.toFloat() },
|
||||||
|
plus = { +it },
|
||||||
|
minus = { -it }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Long -> {
|
||||||
|
unaryNumericOperation(
|
||||||
|
node.op,
|
||||||
|
value,
|
||||||
|
convert = { it.toLong() },
|
||||||
|
plus = { +it },
|
||||||
|
minus = { -it }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Int -> {
|
||||||
|
unaryNumericOperation(
|
||||||
|
node.op,
|
||||||
|
value,
|
||||||
|
convert = { it.toInt() },
|
||||||
|
plus = { +it },
|
||||||
|
minus = { -it }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> throw RuntimeException("Unknown numeric type: ${value.javaClass.name}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSuffixOperation(node: SuffixOperation): Any {
|
||||||
|
val previousValue = currentScope.value(node.reference.symbol.id)
|
||||||
|
val infix = visitInfixOperation(InfixOperation(node.reference, when (node.op) {
|
||||||
|
SuffixOperator.Increment -> InfixOperator.Plus
|
||||||
|
SuffixOperator.Decrement -> InfixOperator.Minus
|
||||||
|
}, IntegerLiteral(1)))
|
||||||
|
currentScope.set(node.reference.symbol.id, infix)
|
||||||
|
return previousValue
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitSetAssignment(node: SetAssignment): Any {
|
override fun visitSetAssignment(node: SetAssignment): Any {
|
||||||
val value = node.value.visit(this)
|
val value = node.value.visit(this)
|
||||||
currentScope.set(node.symbol.id, value)
|
currentScope.set(node.symbol.id, value)
|
||||||
@ -219,6 +275,20 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <T: Number> unaryNumericOperation(
|
||||||
|
op: PrefixOperator,
|
||||||
|
value: Number,
|
||||||
|
convert: (Number) -> T,
|
||||||
|
plus: (T) -> T,
|
||||||
|
minus: (T) -> T
|
||||||
|
): Any {
|
||||||
|
return when (op) {
|
||||||
|
PrefixOperator.UnaryPlus -> plus(convert(value))
|
||||||
|
PrefixOperator.UnaryMinus -> minus(convert(value))
|
||||||
|
else -> throw RuntimeException("Unable to handle operation $op")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitBlock(node: Block): BlockFunction = BlockFunction {
|
override fun visitBlock(node: Block): BlockFunction = BlockFunction {
|
||||||
var value: Any? = null
|
var value: Any? = null
|
||||||
for (expression in node.expressions) {
|
for (expression in node.expressions) {
|
||||||
|
@ -2,6 +2,7 @@ package gay.pizza.pork.evaluator
|
|||||||
|
|
||||||
class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
|
class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
|
||||||
private val functions = mutableMapOf(
|
private val functions = mutableMapOf(
|
||||||
|
"print" to CallableFunction(::printValues),
|
||||||
"println" to CallableFunction(::printLine)
|
"println" to CallableFunction(::printLine)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -9,15 +10,15 @@ class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
|
|||||||
return functions[definition] ?: throw RuntimeException("Unknown Internal Function: $definition")
|
return functions[definition] ?: throw RuntimeException("Unknown Internal Function: $definition")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun printValues(arguments: Arguments): Any {
|
||||||
|
if (quiet || arguments.values.isEmpty()) return None
|
||||||
|
print(arguments.values.joinToString(" "))
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
private fun printLine(arguments: Arguments): Any {
|
private fun printLine(arguments: Arguments): Any {
|
||||||
if (quiet) {
|
if (quiet) return None
|
||||||
return None
|
println(arguments.values.joinToString(" "))
|
||||||
}
|
|
||||||
when (arguments.values.count()) {
|
|
||||||
0 -> println()
|
|
||||||
1 -> println(arguments.values[0])
|
|
||||||
else -> println(arguments.values.joinToString(" "))
|
|
||||||
}
|
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
examples/suffix.pork
Normal file
20
examples/suffix.pork
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* Barber shop sign generator! */
|
||||||
|
func generatePole(width, height) {
|
||||||
|
var i = 0
|
||||||
|
while i < height {
|
||||||
|
let index = i++ mod width
|
||||||
|
var j = 0
|
||||||
|
while j < width {
|
||||||
|
if j == index { print("#") } else { print("_") }
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export func main() {
|
||||||
|
println("nobody:")
|
||||||
|
println()
|
||||||
|
println("barber pole:")
|
||||||
|
generatePole(6, 18)
|
||||||
|
}
|
6
examples/unary.pork
Normal file
6
examples/unary.pork
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export func main() {
|
||||||
|
let constant = -42
|
||||||
|
println("constant set by unary minus: ", constant)
|
||||||
|
println("constant modified by unary minus:", -constant)
|
||||||
|
println("constant modified by unary plus: ", +constant)
|
||||||
|
}
|
@ -66,7 +66,12 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
expect(TokenType.RightParentheses)
|
expect(TokenType.RightParentheses)
|
||||||
FunctionCall(symbol, arguments)
|
FunctionCall(symbol, arguments)
|
||||||
} else {
|
} else {
|
||||||
SymbolReference(symbol)
|
val reference = SymbolReference(symbol)
|
||||||
|
if (peek(TokenType.PlusPlus, TokenType.MinusMinus)) {
|
||||||
|
expect(TokenType.PlusPlus, TokenType.MinusMinus) {
|
||||||
|
SuffixOperation(convertSuffixOperator(it), reference)
|
||||||
|
}
|
||||||
|
} else reference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,8 +83,8 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun readPrefixOperation(): PrefixOperation = within {
|
private fun readPrefixOperation(): PrefixOperation = within {
|
||||||
expect(TokenType.Negation) {
|
expect(TokenType.Negation, TokenType.Plus, TokenType.Minus) {
|
||||||
PrefixOperation(PrefixOperator.Negate, readExpression())
|
PrefixOperation(convertPrefixOperator(it), readExpression())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +148,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
readParentheses()
|
readParentheses()
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenType.Negation -> {
|
TokenType.Negation, TokenType.Plus, TokenType.Minus -> {
|
||||||
readPrefixOperation()
|
readPrefixOperation()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,22 +293,33 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertInfixOperator(token: Token): InfixOperator =
|
private fun convertInfixOperator(token: Token): InfixOperator = when (token.type) {
|
||||||
when (token.type) {
|
TokenType.Plus -> InfixOperator.Plus
|
||||||
TokenType.Plus -> InfixOperator.Plus
|
TokenType.Minus -> InfixOperator.Minus
|
||||||
TokenType.Minus -> InfixOperator.Minus
|
TokenType.Multiply -> InfixOperator.Multiply
|
||||||
TokenType.Multiply -> InfixOperator.Multiply
|
TokenType.Divide -> InfixOperator.Divide
|
||||||
TokenType.Divide -> InfixOperator.Divide
|
TokenType.Equality -> InfixOperator.Equals
|
||||||
TokenType.Equality -> InfixOperator.Equals
|
TokenType.Inequality -> InfixOperator.NotEquals
|
||||||
TokenType.Inequality -> InfixOperator.NotEquals
|
TokenType.Mod -> InfixOperator.EuclideanModulo
|
||||||
TokenType.Mod -> InfixOperator.EuclideanModulo
|
TokenType.Rem -> InfixOperator.Remainder
|
||||||
TokenType.Rem -> InfixOperator.Remainder
|
TokenType.Lesser -> InfixOperator.Lesser
|
||||||
TokenType.Lesser -> InfixOperator.Lesser
|
TokenType.Greater -> InfixOperator.Greater
|
||||||
TokenType.Greater -> InfixOperator.Greater
|
TokenType.LesserEqual -> InfixOperator.LesserEqual
|
||||||
TokenType.LesserEqual -> InfixOperator.LesserEqual
|
TokenType.GreaterEqual -> InfixOperator.GreaterEqual
|
||||||
TokenType.GreaterEqual -> InfixOperator.GreaterEqual
|
else -> throw RuntimeException("Unknown Infix Operator")
|
||||||
else -> throw RuntimeException("Unknown Infix Operator")
|
}
|
||||||
}
|
|
||||||
|
private fun convertPrefixOperator(token: Token): PrefixOperator = when (token.type) {
|
||||||
|
TokenType.Plus -> PrefixOperator.UnaryPlus
|
||||||
|
TokenType.Minus -> PrefixOperator.UnaryMinus
|
||||||
|
else -> throw RuntimeException("Unknown Prefix Operator")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertSuffixOperator(token: Token): SuffixOperator = when (token.type) {
|
||||||
|
TokenType.PlusPlus -> SuffixOperator.Increment
|
||||||
|
TokenType.MinusMinus -> SuffixOperator.Decrement
|
||||||
|
else -> throw RuntimeException("Unknown Suffix Operator")
|
||||||
|
}
|
||||||
|
|
||||||
fun readCompilationUnit(): CompilationUnit = within {
|
fun readCompilationUnit(): CompilationUnit = within {
|
||||||
val declarations = mutableListOf<Declaration>()
|
val declarations = mutableListOf<Declaration>()
|
||||||
|
@ -120,6 +120,11 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
|
|||||||
visit(node.expression)
|
visit(node.expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitSuffixOperation(node: SuffixOperation) {
|
||||||
|
visit(node.reference)
|
||||||
|
append(node.op.token)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitSetAssignment(node: SetAssignment) {
|
override fun visitSetAssignment(node: SetAssignment) {
|
||||||
visit(node.symbol)
|
visit(node.symbol)
|
||||||
append(" = ")
|
append(" = ")
|
||||||
|
@ -15,8 +15,10 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
|||||||
Equality(OperatorFamily),
|
Equality(OperatorFamily),
|
||||||
Inequality(OperatorFamily),
|
Inequality(OperatorFamily),
|
||||||
Equals(SingleChar('='), Promotion('=', Equality)),
|
Equals(SingleChar('='), Promotion('=', Equality)),
|
||||||
Plus(SingleChar('+'), OperatorFamily),
|
PlusPlus(ManyChars("++"), OperatorFamily),
|
||||||
Minus(SingleChar('-'), OperatorFamily),
|
MinusMinus(ManyChars("--"), OperatorFamily),
|
||||||
|
Plus(SingleChar('+'), OperatorFamily, Promotion('+', PlusPlus)),
|
||||||
|
Minus(SingleChar('-'), OperatorFamily, Promotion('-', MinusMinus)),
|
||||||
Multiply(SingleChar('*'), OperatorFamily),
|
Multiply(SingleChar('*'), OperatorFamily),
|
||||||
Divide(SingleChar('/'), OperatorFamily),
|
Divide(SingleChar('/'), OperatorFamily),
|
||||||
LesserEqual(OperatorFamily),
|
LesserEqual(OperatorFamily),
|
||||||
|
@ -9,6 +9,7 @@ class Tokenizer(val source: CharSource) {
|
|||||||
var endOfComment = false
|
var endOfComment = false
|
||||||
while (true) {
|
while (true) {
|
||||||
val char = source.next()
|
val char = source.next()
|
||||||
|
if (char == CharSource.NullChar) throw RuntimeException("Unterminated block comment")
|
||||||
append(char)
|
append(char)
|
||||||
|
|
||||||
if (endOfComment) {
|
if (endOfComment) {
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
export func println(messages...)
|
export func print(values...)
|
||||||
|
native internal "print"
|
||||||
|
|
||||||
|
export func println(values...)
|
||||||
native internal "println"
|
native internal "println"
|
||||||
|
Loading…
Reference in New Issue
Block a user