mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 12:50:55 +00:00
implement support for setting indexed values
This commit is contained in:
parent
48e19a8068
commit
3dcac2f9e6
@ -59,13 +59,22 @@ types:
|
||||
type: Expression
|
||||
- name: typeSpec
|
||||
type: TypeSpec?
|
||||
SetAssignment:
|
||||
SymbolSetAssignment:
|
||||
parent: Expression
|
||||
values:
|
||||
- name: symbol
|
||||
type: Symbol
|
||||
- name: value
|
||||
type: Expression
|
||||
IndexedSetAssignment:
|
||||
parent: Expression
|
||||
values:
|
||||
- name: target
|
||||
type: Expression
|
||||
- name: index
|
||||
type: Expression
|
||||
- name: value
|
||||
type: Expression
|
||||
InfixOperator:
|
||||
values:
|
||||
- name: token
|
||||
|
@ -10,7 +10,8 @@ digraph A {
|
||||
type_CompilationUnit [shape=box,label="CompilationUnit"]
|
||||
type_LetAssignment [shape=box,label="LetAssignment"]
|
||||
type_VarAssignment [shape=box,label="VarAssignment"]
|
||||
type_SetAssignment [shape=box,label="SetAssignment"]
|
||||
type_SymbolSetAssignment [shape=box,label="SymbolSetAssignment"]
|
||||
type_IndexedSetAssignment [shape=box,label="IndexedSetAssignment"]
|
||||
type_InfixOperator [shape=box,label="InfixOperator"]
|
||||
type_InfixOperation [shape=box,label="InfixOperation"]
|
||||
type_BooleanLiteral [shape=box,label="BooleanLiteral"]
|
||||
@ -57,7 +58,8 @@ digraph A {
|
||||
type_Node -> type_NativeTypeDescriptor
|
||||
type_Expression -> type_LetAssignment
|
||||
type_Expression -> type_VarAssignment
|
||||
type_Expression -> type_SetAssignment
|
||||
type_Expression -> type_SymbolSetAssignment
|
||||
type_Expression -> type_IndexedSetAssignment
|
||||
type_Expression -> type_InfixOperation
|
||||
type_Expression -> type_BooleanLiteral
|
||||
type_Expression -> type_FunctionCall
|
||||
@ -94,8 +96,9 @@ digraph A {
|
||||
type_VarAssignment -> type_Symbol [style=dotted]
|
||||
type_VarAssignment -> type_Expression [style=dotted]
|
||||
type_VarAssignment -> type_TypeSpec [style=dotted]
|
||||
type_SetAssignment -> type_Symbol [style=dotted]
|
||||
type_SetAssignment -> type_Expression [style=dotted]
|
||||
type_SymbolSetAssignment -> type_Symbol [style=dotted]
|
||||
type_SymbolSetAssignment -> type_Expression [style=dotted]
|
||||
type_IndexedSetAssignment -> type_Expression [style=dotted]
|
||||
type_InfixOperation -> type_Expression [style=dotted]
|
||||
type_InfixOperation -> type_InfixOperator [style=dotted]
|
||||
type_FunctionCall -> type_Symbol [style=dotted]
|
||||
|
@ -0,0 +1,30 @@
|
||||
// GENERATED CODE FROM PORK AST CODEGEN
|
||||
package gay.pizza.pork.ast.gen
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@SerialName("indexedSetAssignment")
|
||||
class IndexedSetAssignment(val target: Expression, val index: Expression, val value: Expression) : Expression() {
|
||||
override val type: NodeType = NodeType.IndexedSetAssignment
|
||||
|
||||
override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
|
||||
visitor.visitNodes(target, index, value)
|
||||
|
||||
override fun <T> visit(visitor: NodeVisitor<T>): T =
|
||||
visitor.visitIndexedSetAssignment(this)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is IndexedSetAssignment) return false
|
||||
return other.target == target && other.index == index && other.value == value
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = target.hashCode()
|
||||
result = 31 * result + index.hashCode()
|
||||
result = 31 * result + value.hashCode()
|
||||
result = 31 * result + type.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
@ -47,6 +47,9 @@ class NodeCoalescer(val followChildren: Boolean = true, val handler: (Node) -> U
|
||||
override fun visitIndexedBy(node: IndexedBy): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitIndexedSetAssignment(node: IndexedSetAssignment): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitInfixOperation(node: InfixOperation): Unit =
|
||||
handle(node)
|
||||
|
||||
@ -83,9 +86,6 @@ class NodeCoalescer(val followChildren: Boolean = true, val handler: (Node) -> U
|
||||
override fun visitReturn(node: Return): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitSetAssignment(node: SetAssignment): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitStringLiteral(node: StringLiteral): Unit =
|
||||
handle(node)
|
||||
|
||||
@ -98,6 +98,9 @@ class NodeCoalescer(val followChildren: Boolean = true, val handler: (Node) -> U
|
||||
override fun visitSymbolReference(node: SymbolReference): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitSymbolSetAssignment(node: SymbolSetAssignment): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitTypeDefinition(node: TypeDefinition): Unit =
|
||||
handle(node)
|
||||
|
||||
|
@ -38,6 +38,8 @@ interface NodeParser {
|
||||
|
||||
fun parseIndexedBy(): IndexedBy
|
||||
|
||||
fun parseIndexedSetAssignment(): IndexedSetAssignment
|
||||
|
||||
fun parseInfixOperation(): InfixOperation
|
||||
|
||||
fun parseIntegerLiteral(): IntegerLiteral
|
||||
@ -62,8 +64,6 @@ interface NodeParser {
|
||||
|
||||
fun parseReturn(): Return
|
||||
|
||||
fun parseSetAssignment(): SetAssignment
|
||||
|
||||
fun parseStringLiteral(): StringLiteral
|
||||
|
||||
fun parseSuffixOperation(): SuffixOperation
|
||||
@ -72,6 +72,8 @@ interface NodeParser {
|
||||
|
||||
fun parseSymbolReference(): SymbolReference
|
||||
|
||||
fun parseSymbolSetAssignment(): SymbolSetAssignment
|
||||
|
||||
fun parseTypeDefinition(): TypeDefinition
|
||||
|
||||
fun parseTypeSpec(): TypeSpec
|
||||
|
@ -12,7 +12,8 @@ fun NodeParser.parse(type: NodeType): Node =
|
||||
NodeType.CompilationUnit -> parseCompilationUnit()
|
||||
NodeType.LetAssignment -> parseLetAssignment()
|
||||
NodeType.VarAssignment -> parseVarAssignment()
|
||||
NodeType.SetAssignment -> parseSetAssignment()
|
||||
NodeType.SymbolSetAssignment -> parseSymbolSetAssignment()
|
||||
NodeType.IndexedSetAssignment -> parseIndexedSetAssignment()
|
||||
NodeType.InfixOperation -> parseInfixOperation()
|
||||
NodeType.BooleanLiteral -> parseBooleanLiteral()
|
||||
NodeType.FunctionCall -> parseFunctionCall()
|
||||
|
@ -21,6 +21,7 @@ enum class NodeType(val parent: NodeType? = null) {
|
||||
ImportDeclaration(Declaration),
|
||||
ImportPath(Node),
|
||||
IndexedBy(Expression),
|
||||
IndexedSetAssignment(Expression),
|
||||
InfixOperation(Expression),
|
||||
IntegerLiteral(Expression),
|
||||
LetAssignment(Expression),
|
||||
@ -33,11 +34,11 @@ enum class NodeType(val parent: NodeType? = null) {
|
||||
Parentheses(Expression),
|
||||
PrefixOperation(Expression),
|
||||
Return(Expression),
|
||||
SetAssignment(Expression),
|
||||
StringLiteral(Expression),
|
||||
SuffixOperation(Expression),
|
||||
Symbol(Node),
|
||||
SymbolReference(Expression),
|
||||
SymbolSetAssignment(Expression),
|
||||
TypeDefinition(Definition),
|
||||
TypeSpec(Node),
|
||||
VarAssignment(Expression),
|
||||
|
@ -32,6 +32,8 @@ interface NodeVisitor<T> {
|
||||
|
||||
fun visitIndexedBy(node: IndexedBy): T
|
||||
|
||||
fun visitIndexedSetAssignment(node: IndexedSetAssignment): T
|
||||
|
||||
fun visitInfixOperation(node: InfixOperation): T
|
||||
|
||||
fun visitIntegerLiteral(node: IntegerLiteral): T
|
||||
@ -56,8 +58,6 @@ interface NodeVisitor<T> {
|
||||
|
||||
fun visitReturn(node: Return): T
|
||||
|
||||
fun visitSetAssignment(node: SetAssignment): T
|
||||
|
||||
fun visitStringLiteral(node: StringLiteral): T
|
||||
|
||||
fun visitSuffixOperation(node: SuffixOperation): T
|
||||
@ -66,6 +66,8 @@ interface NodeVisitor<T> {
|
||||
|
||||
fun visitSymbolReference(node: SymbolReference): T
|
||||
|
||||
fun visitSymbolSetAssignment(node: SymbolSetAssignment): T
|
||||
|
||||
fun visitTypeDefinition(node: TypeDefinition): T
|
||||
|
||||
fun visitTypeSpec(node: TypeSpec): T
|
||||
|
@ -9,7 +9,8 @@ fun <T> NodeVisitor<T>.visit(node: Node): T =
|
||||
is CompilationUnit -> visitCompilationUnit(node)
|
||||
is LetAssignment -> visitLetAssignment(node)
|
||||
is VarAssignment -> visitVarAssignment(node)
|
||||
is SetAssignment -> visitSetAssignment(node)
|
||||
is SymbolSetAssignment -> visitSymbolSetAssignment(node)
|
||||
is IndexedSetAssignment -> visitIndexedSetAssignment(node)
|
||||
is InfixOperation -> visitInfixOperation(node)
|
||||
is BooleanLiteral -> visitBooleanLiteral(node)
|
||||
is FunctionCall -> visitFunctionCall(node)
|
||||
|
@ -5,18 +5,18 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@SerialName("setAssignment")
|
||||
class SetAssignment(val symbol: Symbol, val value: Expression) : Expression() {
|
||||
override val type: NodeType = NodeType.SetAssignment
|
||||
@SerialName("symbolSetAssignment")
|
||||
class SymbolSetAssignment(val symbol: Symbol, val value: Expression) : Expression() {
|
||||
override val type: NodeType = NodeType.SymbolSetAssignment
|
||||
|
||||
override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
|
||||
visitor.visitNodes(symbol, value)
|
||||
|
||||
override fun <T> visit(visitor: NodeVisitor<T>): T =
|
||||
visitor.visitSetAssignment(this)
|
||||
visitor.visitSymbolSetAssignment(this)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is SetAssignment) return false
|
||||
if (other !is SymbolSetAssignment) return false
|
||||
return other.symbol == symbol && other.value == value
|
||||
}
|
||||
|
@ -3,9 +3,12 @@ package gay.pizza.pork.bir
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class IrIndex(var data: IrCodeElement, var index: IrCodeElement) : IrCodeElement() {
|
||||
data class IrIndex(var data: IrCodeElement, var index: IrCodeElement, var value: IrCodeElement? = null) : IrCodeElement() {
|
||||
override fun crawl(block: (IrElement) -> Unit) {
|
||||
block(data)
|
||||
block(index)
|
||||
if (value != null) {
|
||||
block(value!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ enum class Opcode(val id: UByte) {
|
||||
EuclideanModulo(37u),
|
||||
Remainder(38u),
|
||||
Index(39u),
|
||||
IndexSet(44u),
|
||||
ScopeIn(40u),
|
||||
ScopeOut(41u),
|
||||
ReturnAddress(42u),
|
||||
|
@ -228,6 +228,12 @@ class AstIrEmitter(
|
||||
index = visit(node.index)
|
||||
)
|
||||
|
||||
override fun visitIndexedSetAssignment(node: IndexedSetAssignment): IrCodeElement = IrIndex(
|
||||
data = visit(node.target),
|
||||
index = visit(node.index),
|
||||
value = visit(node.value),
|
||||
)
|
||||
|
||||
override fun visitInfixOperation(node: InfixOperation): IrCodeElement {
|
||||
val op = when (node.op) {
|
||||
InfixOperator.Plus -> IrInfixOp.Add
|
||||
@ -288,7 +294,7 @@ class AstIrEmitter(
|
||||
override fun visitReturn(node: Return): IrCodeElement =
|
||||
IrReturn(from = self, value = node.value.visit(this))
|
||||
|
||||
override fun visitSetAssignment(node: SetAssignment): IrCodeElement {
|
||||
override fun visitSymbolSetAssignment(node: SymbolSetAssignment): IrCodeElement {
|
||||
val symbol = lookupLocalVariable(node.symbol) ?:
|
||||
throw CompileError("Unable to find local variable target '${node.symbol.id}'", node)
|
||||
return IrStore(symbol, node.value.visit(this))
|
||||
|
@ -248,9 +248,16 @@ class IrStubOpEmitter(val irDefinition: IrDefinition, val code: CodeBuilder) : I
|
||||
}
|
||||
|
||||
override fun visitIrIndex(ir: IrIndex) {
|
||||
if (ir.value != null) {
|
||||
visit(ir.value!!)
|
||||
}
|
||||
visit(ir.index)
|
||||
visit(ir.data)
|
||||
code.emit(Opcode.Index)
|
||||
if (ir.value != null) {
|
||||
code.emit(Opcode.IndexSet)
|
||||
} else {
|
||||
code.emit(Opcode.Index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitIrListSize(ir: IrListSize) {
|
||||
|
@ -177,7 +177,7 @@ class EvaluationVisitor(root: Scope, val stack: CallStack) : FunctionLevelVisito
|
||||
return previousValue
|
||||
}
|
||||
|
||||
override fun visitSetAssignment(node: SetAssignment): Any {
|
||||
override fun visitSymbolSetAssignment(node: SymbolSetAssignment): Any {
|
||||
val value = node.value.visit(this)
|
||||
currentScope.set(node.symbol.id, value)
|
||||
return value
|
||||
@ -399,6 +399,24 @@ class EvaluationVisitor(root: Scope, val stack: CallStack) : FunctionLevelVisito
|
||||
throw RuntimeException("Failed to index '${value}' by '${index}': Unsupported types used.")
|
||||
}
|
||||
|
||||
override fun visitIndexedSetAssignment(node: IndexedSetAssignment): Any {
|
||||
val value = node.value.visit(this)
|
||||
val index = node.index.visit(this)
|
||||
val target = node.target.visit(this)
|
||||
if (target is MutableList<*> && index is Number) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(target as MutableList<Any?>)[index.toInt()] = value
|
||||
return None
|
||||
}
|
||||
|
||||
if (target is Array<*> && index is Number) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(target as MutableList<Any?>)[index.toInt()] = value
|
||||
return None
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun visitNoneLiteral(node: NoneLiteral): Any = None
|
||||
|
||||
override fun visitContinue(node: Continue): Any = ContinueMarker
|
||||
|
@ -73,8 +73,8 @@ func setCell(cells, swap, x, y, state) {
|
||||
let mask = if swap { 2 } else { 1 }
|
||||
let idx = x + y * gridWidth
|
||||
let value = cells[idx]
|
||||
if state { listSet(cells, idx, value | mask) }
|
||||
else { listSet(cells, idx, value & (~mask)) }
|
||||
if state { cells[idx] = value | mask }
|
||||
else { cells[idx] = value & (~mask) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
export func main() {
|
||||
let items = [["Hello"], ["Goodbye"]]
|
||||
println(items[0][0])
|
||||
items[0][0] = "Goodbye"
|
||||
println(items[0][0])
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package gay.pizza.pork.frontend.scope
|
||||
|
||||
import gay.pizza.pork.ast.FunctionLevelVisitor
|
||||
import gay.pizza.pork.ast.gen.*
|
||||
import gay.pizza.pork.ast.gen.visit
|
||||
|
||||
class ExternalSymbolUsageAnalyzer : FunctionLevelVisitor<Unit>() {
|
||||
private val symbols = mutableSetOf<Symbol>()
|
||||
@ -116,8 +117,13 @@ class ExternalSymbolUsageAnalyzer : FunctionLevelVisitor<Unit>() {
|
||||
node.visitChildren(this)
|
||||
}
|
||||
|
||||
override fun visitSetAssignment(node: SetAssignment) {
|
||||
node.value.visit(this)
|
||||
override fun visitSymbolSetAssignment(node: SymbolSetAssignment) {
|
||||
checkAndContribute(node.symbol)
|
||||
node.visitChildren(this)
|
||||
}
|
||||
|
||||
override fun visitIndexedSetAssignment(node: IndexedSetAssignment) {
|
||||
node.visitChildren(this)
|
||||
}
|
||||
|
||||
override fun visitStringLiteral(node: StringLiteral) {
|
||||
|
@ -53,16 +53,6 @@ class Parser(source: TokenSource, attribution: NodeAttribution) :
|
||||
}
|
||||
}
|
||||
|
||||
if (expression is SymbolReference && peek(TokenType.Equals)) {
|
||||
val symbolReference = expression
|
||||
expression = produce(NodeType.SetAssignment) {
|
||||
attribution.adopt(expression)
|
||||
expect(TokenType.Equals)
|
||||
val value = parseExpression()
|
||||
SetAssignment(symbolReference.symbol, value)
|
||||
}
|
||||
}
|
||||
|
||||
while (peek(TokenType.LeftBracket)) {
|
||||
expression = produce(NodeType.IndexedBy) {
|
||||
attribution.adopt(expression)
|
||||
@ -73,12 +63,33 @@ class Parser(source: TokenSource, attribution: NodeAttribution) :
|
||||
}
|
||||
}
|
||||
|
||||
if (expression is SymbolReference && peek(TokenType.Equals)) {
|
||||
val symbolReference = expression
|
||||
expression = produce(NodeType.SymbolSetAssignment) {
|
||||
attribution.adopt(expression)
|
||||
expect(TokenType.Equals)
|
||||
val value = parseExpression()
|
||||
SymbolSetAssignment(symbolReference.symbol, value)
|
||||
}
|
||||
}
|
||||
|
||||
if (expression is IndexedBy && peek(TokenType.Equals)) {
|
||||
val indexedBy = expression
|
||||
expression = produce(NodeType.IndexedSetAssignment) {
|
||||
attribution.adopt(indexedBy)
|
||||
expect(TokenType.Equals)
|
||||
val value = parseExpression()
|
||||
IndexedSetAssignment(target = indexedBy.expression, index = indexedBy.index, value = value)
|
||||
}
|
||||
}
|
||||
|
||||
return if (peek(
|
||||
TokenType.Plus, TokenType.Minus, TokenType.Multiply, TokenType.Divide, TokenType.Ampersand,
|
||||
TokenType.Pipe, TokenType.Caret, TokenType.Equality, TokenType.Inequality, TokenType.Mod,
|
||||
TokenType.Rem, TokenType.Lesser, TokenType.Greater, TokenType.LesserEqual, TokenType.GreaterEqual,
|
||||
TokenType.And, TokenType.Or)) {
|
||||
produce(NodeType.InfixOperation) {
|
||||
attribution.adopt(expression)
|
||||
val infixToken = next()
|
||||
val infixOperator = ParserHelpers.convertInfixOperator(infixToken)
|
||||
InfixOperation(expression, infixOperator, parseExpression())
|
||||
@ -263,6 +274,16 @@ class Parser(source: TokenSource, attribution: NodeAttribution) :
|
||||
IndexedBy(expression, index)
|
||||
}
|
||||
|
||||
override fun parseIndexedSetAssignment(): IndexedSetAssignment = produce(NodeType.IndexedSetAssignment) {
|
||||
val target = parseExpression()
|
||||
expect(TokenType.LeftBracket)
|
||||
val index = parseExpression()
|
||||
expect(TokenType.RightBracket)
|
||||
expect(TokenType.Equals)
|
||||
val value = parseExpression()
|
||||
IndexedSetAssignment(target, index, value)
|
||||
}
|
||||
|
||||
override fun parseInfixOperation(): InfixOperation = produce(NodeType.InfixOperation) {
|
||||
val infixToken = next()
|
||||
val infixOperator = ParserHelpers.convertInfixOperator(infixToken)
|
||||
@ -363,11 +384,11 @@ class Parser(source: TokenSource, attribution: NodeAttribution) :
|
||||
Return(parseExpression())
|
||||
}
|
||||
|
||||
override fun parseSetAssignment(): SetAssignment = produce(NodeType.SetAssignment) {
|
||||
override fun parseSymbolSetAssignment(): SymbolSetAssignment = produce(NodeType.SymbolSetAssignment) {
|
||||
val symbol = parseSymbol()
|
||||
expect(TokenType.Equals)
|
||||
val value = parseExpression()
|
||||
SetAssignment(symbol, value)
|
||||
SymbolSetAssignment(symbol, value)
|
||||
}
|
||||
|
||||
override fun parseStringLiteral(): StringLiteral = produce(NodeType.StringLiteral) {
|
||||
|
@ -202,7 +202,7 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
|
||||
append(node.op.token)
|
||||
}
|
||||
|
||||
override fun visitSetAssignment(node: SetAssignment) {
|
||||
override fun visitSymbolSetAssignment(node: SymbolSetAssignment) {
|
||||
visit(node.symbol)
|
||||
append(" = ")
|
||||
visit(node.value)
|
||||
@ -304,6 +304,15 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
|
||||
append("]")
|
||||
}
|
||||
|
||||
override fun visitIndexedSetAssignment(node: IndexedSetAssignment) {
|
||||
visit(node.target)
|
||||
append("[")
|
||||
visit(node.index)
|
||||
append("]")
|
||||
append(" = ")
|
||||
visit(node.value)
|
||||
}
|
||||
|
||||
override fun visitCompilationUnit(node: CompilationUnit) {
|
||||
for (declaration in node.declarations) {
|
||||
visit(declaration)
|
||||
|
@ -0,0 +1,15 @@
|
||||
// GENERATED CODE FROM PORK AST CODEGEN
|
||||
package gay.pizza.pork.idea.psi.gen
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.navigation.ItemPresentation
|
||||
import gay.pizza.pork.idea.psi.PorkElementHelpers
|
||||
import javax.swing.Icon
|
||||
|
||||
class IndexedSetAssignmentElement(node: ASTNode) : PorkElement(node) {
|
||||
override fun getIcon(flags: Int): Icon? =
|
||||
PorkElementHelpers.iconOf(this)
|
||||
|
||||
override fun getPresentation(): ItemPresentation? =
|
||||
PorkElementHelpers.presentationOf(this)
|
||||
}
|
@ -16,7 +16,8 @@ object PorkElementFactory {
|
||||
NodeType.CompilationUnit -> CompilationUnitElement(node)
|
||||
NodeType.LetAssignment -> LetAssignmentElement(node)
|
||||
NodeType.VarAssignment -> VarAssignmentElement(node)
|
||||
NodeType.SetAssignment -> SetAssignmentElement(node)
|
||||
NodeType.SymbolSetAssignment -> SymbolSetAssignmentElement(node)
|
||||
NodeType.IndexedSetAssignment -> IndexedSetAssignmentElement(node)
|
||||
NodeType.InfixOperation -> InfixOperationElement(node)
|
||||
NodeType.BooleanLiteral -> BooleanLiteralElement(node)
|
||||
NodeType.FunctionCall -> FunctionCallElement(node)
|
||||
|
@ -6,7 +6,7 @@ import com.intellij.navigation.ItemPresentation
|
||||
import gay.pizza.pork.idea.psi.PorkElementHelpers
|
||||
import javax.swing.Icon
|
||||
|
||||
class SetAssignmentElement(node: ASTNode) : PorkElement(node) {
|
||||
class SymbolSetAssignmentElement(node: ASTNode) : PorkElement(node) {
|
||||
override fun getIcon(flags: Int): Icon? =
|
||||
PorkElementHelpers.iconOf(this)
|
||||
|
@ -15,6 +15,7 @@ val StandardOpHandlers: List<OpHandler> = listOf(
|
||||
ListSizeOpHandler,
|
||||
|
||||
IndexOpHandler,
|
||||
IndexSetOpHandler,
|
||||
|
||||
AndOpHandler,
|
||||
OrOpHandler,
|
||||
|
@ -0,0 +1,15 @@
|
||||
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 IndexSetOpHandler : OpHandler(Opcode.IndexSet) {
|
||||
override fun handle(machine: InternalMachine, op: Op) {
|
||||
val list = machine.pop<MutableList<Any>>()
|
||||
val index = machine.pop<Number>().toInt()
|
||||
val value = machine.pop<Any>()
|
||||
list[index] = value
|
||||
}
|
||||
}
|
@ -13,6 +13,6 @@ object ListMakeOpHandler : OpHandler(Opcode.ListMake) {
|
||||
val item = machine.popAnyValue()
|
||||
list.add(item)
|
||||
}
|
||||
machine.push(list.reversed())
|
||||
machine.push(list.reversed().toMutableList())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user