diff --git a/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt b/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt index a2e9cfb..71f3bde 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt @@ -42,8 +42,8 @@ interface NodeVisitor { else -> throw RuntimeException("Unknown Node") } - fun visitNodes(vararg nodes: Node): List = - nodes.map { visit(it) } + fun visitNodes(vararg nodes: Node?): List = + nodes.filterNotNull().map { visit(it) } fun visitAll(vararg nodeLists: List): List = nodeLists.asSequence().flatten().map { visit(it) }.toList() diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/BooleanLiteral.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/BooleanLiteral.kt index 28d95b9..f2368d8 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/BooleanLiteral.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/BooleanLiteral.kt @@ -4,4 +4,15 @@ import gay.pizza.pork.ast.NodeType class BooleanLiteral(val value: Boolean) : Expression() { override val type: NodeType = NodeType.BooleanLiteral + + override fun equals(other: Any?): Boolean { + if (other !is BooleanLiteral) return false + return other.value == value + } + + override fun hashCode(): Int { + var result = value.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/Define.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/Define.kt index 0b0bb5d..adc8d2d 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/Define.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/Define.kt @@ -8,4 +8,16 @@ class Define(val symbol: Symbol, val value: Expression) : Expression() { override fun visitChildren(visitor: NodeVisitor): List = visitor.visitNodes(symbol, value) + + override fun equals(other: Any?): Boolean { + if (other !is Define) return false + return other.symbol == symbol && other.value == value + } + + override fun hashCode(): Int { + var result = symbol.hashCode() + result = 31 * result + value.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/FunctionCall.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/FunctionCall.kt index 67ad888..12b23b3 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/FunctionCall.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/FunctionCall.kt @@ -8,4 +8,9 @@ class FunctionCall(val symbol: Symbol, val arguments: List) : Expres override fun visitChildren(visitor: NodeVisitor): List = visitor.visitAll(listOf(symbol), arguments) + + override fun equals(other: Any?): Boolean { + if (other !is FunctionCall) return false + return other.symbol == symbol && other.arguments == arguments + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/If.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/If.kt index 39ccbe7..aed20ee 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/If.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/If.kt @@ -1,6 +1,7 @@ package gay.pizza.pork.ast.nodes import gay.pizza.pork.ast.NodeType +import gay.pizza.pork.ast.NodeVisitor class If( val condition: Expression, @@ -8,4 +9,22 @@ class If( val elseExpression: Expression? = null ) : Expression() { override val type: NodeType = NodeType.If + + override fun visitChildren(visitor: NodeVisitor): List = + visitor.visitNodes(condition, thenExpression, elseExpression) + + override fun equals(other: Any?): Boolean { + if (other !is If) return false + return other.condition == condition && + other.thenExpression == thenExpression && + other.elseExpression == elseExpression + } + + override fun hashCode(): Int { + var result = condition.hashCode() + result = 31 * result + thenExpression.hashCode() + result = 31 * result + (elseExpression?.hashCode() ?: 0) + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/InfixOperation.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/InfixOperation.kt index e863664..043d3bb 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/InfixOperation.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/InfixOperation.kt @@ -3,9 +3,28 @@ package gay.pizza.pork.ast.nodes import gay.pizza.pork.ast.NodeType import gay.pizza.pork.ast.NodeVisitor -class InfixOperation(val left: Expression, val op: InfixOperator, val right: Expression) : Expression() { +class InfixOperation( + val left: Expression, + val op: InfixOperator, + val right: Expression +) : Expression() { override val type: NodeType = NodeType.InfixOperation override fun visitChildren(visitor: NodeVisitor): List = visitor.visitNodes(left, right) + + override fun equals(other: Any?): Boolean { + if (other !is InfixOperation) return false + return other.op == op && + other.left == left && + other.right == right + } + + override fun hashCode(): Int { + var result = left.hashCode() + result = 31 * result + op.hashCode() + result = 31 * result + right.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/IntLiteral.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/IntLiteral.kt index af2e034..4966b39 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/IntLiteral.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/IntLiteral.kt @@ -4,4 +4,15 @@ import gay.pizza.pork.ast.NodeType class IntLiteral(val value: Int) : Expression() { override val type: NodeType = NodeType.IntLiteral + + override fun equals(other: Any?): Boolean { + if (other !is IntLiteral) return false + return other.value == value + } + + override fun hashCode(): Int { + var result = value + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/Lambda.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/Lambda.kt index 0b92492..156de36 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/Lambda.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/Lambda.kt @@ -8,4 +8,16 @@ class Lambda(val arguments: List, val expressions: List) : E override fun visitChildren(visitor: NodeVisitor): List = visitor.visitAll(arguments, expressions) + + override fun equals(other: Any?): Boolean { + if (other !is Lambda) return false + return other.arguments == arguments && other.expressions == expressions + } + + override fun hashCode(): Int { + var result = arguments.hashCode() + result = 31 * result + expressions.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/ListLiteral.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/ListLiteral.kt index 2685e99..64a2b1a 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/ListLiteral.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/ListLiteral.kt @@ -8,4 +8,15 @@ class ListLiteral(val items: List) : Expression() { override fun visitChildren(visitor: NodeVisitor): List = visitor.visitAll(items) + + override fun equals(other: Any?): Boolean { + if (other !is ListLiteral) return false + return other.items == items + } + + override fun hashCode(): Int { + var result = items.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/Parentheses.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/Parentheses.kt index 9bb8e6c..b7be5fc 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/Parentheses.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/Parentheses.kt @@ -8,4 +8,15 @@ class Parentheses(val expression: Expression) : Expression() { override fun visitChildren(visitor: NodeVisitor): List = visitor.visitNodes(expression) + + override fun equals(other: Any?): Boolean { + if (other !is Parentheses) return false + return other.expression == expression + } + + override fun hashCode(): Int { + var result = expression.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/PrefixOperation.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/PrefixOperation.kt index 24c0b3a..dd00638 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/PrefixOperation.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/PrefixOperation.kt @@ -1,7 +1,23 @@ package gay.pizza.pork.ast.nodes import gay.pizza.pork.ast.NodeType +import gay.pizza.pork.ast.NodeVisitor class PrefixOperation(val op: PrefixOperator, val expression: Expression) : Expression() { override val type: NodeType = NodeType.PrefixOperation + + override fun visitChildren(visitor: NodeVisitor): List = + visitor.visitNodes(expression) + + override fun equals(other: Any?): Boolean { + if (other !is PrefixOperation) return false + return other.op == op && other.expression == expression + } + + override fun hashCode(): Int { + var result = op.hashCode() + result = 31 * result + expression.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/Program.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/Program.kt index 1871444..586b922 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/Program.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/Program.kt @@ -8,4 +8,15 @@ class Program(val expressions: List) : Node() { override fun visitChildren(visitor: NodeVisitor): List = visitor.visitAll(expressions) + + override fun equals(other: Any?): Boolean { + if (other !is Program) return false + return other.expressions == expressions + } + + override fun hashCode(): Int { + var result = expressions.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/Symbol.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/Symbol.kt index 1cad7ae..6efaf42 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/Symbol.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/Symbol.kt @@ -4,4 +4,15 @@ import gay.pizza.pork.ast.NodeType class Symbol(val id: String) : Node() { override val type: NodeType = NodeType.Symbol + + override fun equals(other: Any?): Boolean { + if (other !is Symbol) return false + return other.id == id + } + + override fun hashCode(): Int { + var result = id.hashCode() + result = 31 * result + type.hashCode() + return result + } } diff --git a/src/main/kotlin/gay/pizza/pork/ast/nodes/SymbolReference.kt b/src/main/kotlin/gay/pizza/pork/ast/nodes/SymbolReference.kt index 78816d2..3156376 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/nodes/SymbolReference.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/nodes/SymbolReference.kt @@ -8,4 +8,15 @@ class SymbolReference(val symbol: Symbol) : Expression() { override fun visitChildren(visitor: NodeVisitor): List = visitor.visitNodes(symbol) + + override fun equals(other: Any?): Boolean { + if (other !is SymbolReference) return false + return other.symbol == symbol + } + + override fun hashCode(): Int { + var result = symbol.hashCode() + result = 31 * result + type.hashCode() + return result + } }