mirror of
				https://github.com/GayPizzaSpecifications/pork.git
				synced 2025-11-03 17:39:38 +00:00 
			
		
		
		
	Implement negation operator.
This commit is contained in:
		@ -19,7 +19,7 @@ main = { in
 | 
				
			|||||||
  falseValue = false
 | 
					  falseValue = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  invert = { value in
 | 
					  invert = { value in
 | 
				
			||||||
    if value then false else true
 | 
					    !value
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [
 | 
					  [
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,8 @@ enum class NodeType(val parent: NodeType? = null, vararg traits: NodeTypeTrait)
 | 
				
			|||||||
  Parentheses(Expression),
 | 
					  Parentheses(Expression),
 | 
				
			||||||
  Define(Expression),
 | 
					  Define(Expression),
 | 
				
			||||||
  Lambda(Expression),
 | 
					  Lambda(Expression),
 | 
				
			||||||
  InfixOperation(Expression),
 | 
					  PrefixOperation(Expression, Operation),
 | 
				
			||||||
 | 
					  InfixOperation(Expression, Operation),
 | 
				
			||||||
  SymbolReference(Expression),
 | 
					  SymbolReference(Expression),
 | 
				
			||||||
  FunctionCall(Expression),
 | 
					  FunctionCall(Expression),
 | 
				
			||||||
  If(Expression);
 | 
					  If(Expression);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,5 +2,6 @@ package gay.pizza.pork.ast
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
enum class NodeTypeTrait {
 | 
					enum class NodeTypeTrait {
 | 
				
			||||||
  Intermediate,
 | 
					  Intermediate,
 | 
				
			||||||
 | 
					  Operation,
 | 
				
			||||||
  Literal
 | 
					  Literal
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								src/main/kotlin/gay/pizza/pork/ast/PrefixOperation.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/main/kotlin/gay/pizza/pork/ast/PrefixOperation.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					package gay.pizza.pork.ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PrefixOperation(val op: PrefixOperator, val expression: Expression) : Expression() {
 | 
				
			||||||
 | 
					  override val type: NodeType = NodeType.PrefixOperation
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								src/main/kotlin/gay/pizza/pork/ast/PrefixOperator.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/main/kotlin/gay/pizza/pork/ast/PrefixOperator.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					package gay.pizza.pork.ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum class PrefixOperator(val token: String) {
 | 
				
			||||||
 | 
					  Negate("!")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -111,6 +111,11 @@ class Printer(private val buffer: StringBuilder) : Visitor<Unit> {
 | 
				
			|||||||
    append(")")
 | 
					    append(")")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitPrefixOperation(node: PrefixOperation) {
 | 
				
			||||||
 | 
					    append(node.op.token)
 | 
				
			||||||
 | 
					    visit(node.expression)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitInfixOperation(node: InfixOperation) {
 | 
					  override fun visitInfixOperation(node: InfixOperation) {
 | 
				
			||||||
    visit(node.left)
 | 
					    visit(node.left)
 | 
				
			||||||
    append(" ")
 | 
					    append(" ")
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ interface Visitor<T> {
 | 
				
			|||||||
  fun visitListLiteral(node: ListLiteral): T
 | 
					  fun visitListLiteral(node: ListLiteral): T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fun visitParentheses(node: Parentheses): T
 | 
					  fun visitParentheses(node: Parentheses): T
 | 
				
			||||||
 | 
					  fun visitPrefixOperation(node: PrefixOperation): T
 | 
				
			||||||
  fun visitInfixOperation(node: InfixOperation): T
 | 
					  fun visitInfixOperation(node: InfixOperation): T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fun visitProgram(node: Program): T
 | 
					  fun visitProgram(node: Program): T
 | 
				
			||||||
@ -23,6 +24,7 @@ interface Visitor<T> {
 | 
				
			|||||||
    is ListLiteral -> visitListLiteral(node)
 | 
					    is ListLiteral -> visitListLiteral(node)
 | 
				
			||||||
    is Parentheses -> visitParentheses(node)
 | 
					    is Parentheses -> visitParentheses(node)
 | 
				
			||||||
    is InfixOperation -> visitInfixOperation(node)
 | 
					    is InfixOperation -> visitInfixOperation(node)
 | 
				
			||||||
 | 
					    is PrefixOperation -> visitPrefixOperation(node)
 | 
				
			||||||
    is Define -> visitDefine(node)
 | 
					    is Define -> visitDefine(node)
 | 
				
			||||||
    is Lambda -> visitLambda(node)
 | 
					    is Lambda -> visitLambda(node)
 | 
				
			||||||
    is FunctionCall -> visitFunctionCall(node)
 | 
					    is FunctionCall -> visitFunctionCall(node)
 | 
				
			||||||
 | 
				
			|||||||
@ -57,6 +57,9 @@ class KotlinCompiler : Visitor<String> {
 | 
				
			|||||||
  override fun visitParentheses(node: Parentheses): String =
 | 
					  override fun visitParentheses(node: Parentheses): String =
 | 
				
			||||||
    "(${visit(node.expression)})"
 | 
					    "(${visit(node.expression)})"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitPrefixOperation(node: PrefixOperation): String =
 | 
				
			||||||
 | 
					    "${node.op.token}${visit(node.expression)}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitInfixOperation(node: InfixOperation): String =
 | 
					  override fun visitInfixOperation(node: InfixOperation): String =
 | 
				
			||||||
    "${visit(node.left)} ${node.op.token} ${visit(node.right)}"
 | 
					    "${visit(node.left)} ${node.op.token} ${visit(node.right)}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,18 @@ class PorkEvaluator(root: Scope) : Visitor<Any> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  override fun visitParentheses(node: Parentheses): Any = visit(node.expression)
 | 
					  override fun visitParentheses(node: Parentheses): Any = visit(node.expression)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override fun visitPrefixOperation(node: PrefixOperation): Any {
 | 
				
			||||||
 | 
					    val value = visit(node.expression)
 | 
				
			||||||
 | 
					    return when (node.op) {
 | 
				
			||||||
 | 
					      PrefixOperator.Negate -> {
 | 
				
			||||||
 | 
					        if (value !is Boolean) {
 | 
				
			||||||
 | 
					          throw RuntimeException("Cannot negate a value which is not a boolean.")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        !value
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun visitInfixOperation(node: InfixOperation): Any {
 | 
					  override fun visitInfixOperation(node: InfixOperation): Any {
 | 
				
			||||||
    val left = visit(node.left)
 | 
					    val left = visit(node.left)
 | 
				
			||||||
    val right = visit(node.right)
 | 
					    val right = visit(node.right)
 | 
				
			||||||
 | 
				
			|||||||
@ -96,6 +96,11 @@ class PorkParser(val source: PeekableSource<Token>) {
 | 
				
			|||||||
        return BooleanLiteral(false)
 | 
					        return BooleanLiteral(false)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      TokenType.Negation -> {
 | 
				
			||||||
 | 
					        expect(TokenType.Negation)
 | 
				
			||||||
 | 
					        return PrefixOperation(PrefixOperator.Negate, readExpression())
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      TokenType.If -> {
 | 
					      TokenType.If -> {
 | 
				
			||||||
        return readIf()
 | 
					        return readIf()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@ enum class TokenType(val char: Char? = null, val keyword: String? = null, val pr
 | 
				
			|||||||
  RightBracket(char = ']'),
 | 
					  RightBracket(char = ']'),
 | 
				
			||||||
  LeftParentheses(char = '('),
 | 
					  LeftParentheses(char = '('),
 | 
				
			||||||
  RightParentheses(char = ')'),
 | 
					  RightParentheses(char = ')'),
 | 
				
			||||||
 | 
					  Negation(char = '!'),
 | 
				
			||||||
  Comma(char = ','),
 | 
					  Comma(char = ','),
 | 
				
			||||||
  False(keyword = "false"),
 | 
					  False(keyword = "false"),
 | 
				
			||||||
  True(keyword = "true"),
 | 
					  True(keyword = "true"),
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user