mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 05:10:55 +00:00
add euclidean modulo and remainder infix operators
This commit is contained in:
parent
03c278f5b1
commit
b60326d5be
@ -64,6 +64,12 @@ types:
|
|||||||
- name: NotEquals
|
- name: NotEquals
|
||||||
values:
|
values:
|
||||||
token: "!="
|
token: "!="
|
||||||
|
- name: EuclideanModulo
|
||||||
|
values:
|
||||||
|
token: "mod"
|
||||||
|
- name: Remainder
|
||||||
|
values:
|
||||||
|
token: "rem"
|
||||||
InfixOperation:
|
InfixOperation:
|
||||||
parent: Expression
|
parent: Expression
|
||||||
values:
|
values:
|
||||||
|
@ -12,5 +12,7 @@ enum class InfixOperator(val token: String) {
|
|||||||
Multiply("*"),
|
Multiply("*"),
|
||||||
Divide("/"),
|
Divide("/"),
|
||||||
Equals("=="),
|
Equals("=="),
|
||||||
NotEquals("!=")
|
NotEquals("!="),
|
||||||
|
EuclideanModulo("mod"),
|
||||||
|
Remainder("rem")
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package gay.pizza.pork.evaluator
|
package gay.pizza.pork.evaluator
|
||||||
|
|
||||||
import gay.pizza.pork.ast.*
|
import gay.pizza.pork.ast.*
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||||
private var currentScope: Scope = root
|
private var currentScope: Scope = root
|
||||||
@ -105,7 +106,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
|||||||
add = { a, b -> a + b },
|
add = { a, b -> a + b },
|
||||||
subtract = { a, b -> a - b },
|
subtract = { a, b -> a - b },
|
||||||
multiply = { a, b -> a * b },
|
multiply = { a, b -> a * b },
|
||||||
divide = { a, b -> a / b }
|
divide = { a, b -> a / b },
|
||||||
|
euclideanModulo = { a, b -> throw RuntimeException("Can't perform integer modulo between floating point types") },
|
||||||
|
remainder = { a, b -> throw RuntimeException("Can't perform integer remainder between floating point types") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +121,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
|||||||
add = { a, b -> a + b },
|
add = { a, b -> a + b },
|
||||||
subtract = { a, b -> a - b },
|
subtract = { a, b -> a - b },
|
||||||
multiply = { a, b -> a * b },
|
multiply = { a, b -> a * b },
|
||||||
divide = { a, b -> a / b }
|
divide = { a, b -> a / b },
|
||||||
|
euclideanModulo = { a, b -> throw RuntimeException("Can't perform integer modulo between floating point types") },
|
||||||
|
remainder = { a, b -> throw RuntimeException("Can't perform integer remainder between floating point types") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +136,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
|||||||
add = { a, b -> a + b },
|
add = { a, b -> a + b },
|
||||||
subtract = { a, b -> a - b },
|
subtract = { a, b -> a - b },
|
||||||
multiply = { a, b -> a * b },
|
multiply = { a, b -> a * b },
|
||||||
divide = { a, b -> a / b }
|
divide = { a, b -> a / b },
|
||||||
|
euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
|
||||||
|
remainder = { x, d -> x % d }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +151,9 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
|||||||
add = { a, b -> a + b },
|
add = { a, b -> a + b },
|
||||||
subtract = { a, b -> a - b },
|
subtract = { a, b -> a - b },
|
||||||
multiply = { a, b -> a * b },
|
multiply = { a, b -> a * b },
|
||||||
divide = { a, b -> a / b }
|
divide = { a, b -> a / b },
|
||||||
|
euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
|
||||||
|
remainder = { x, d -> x % d }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,13 +168,17 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
|||||||
add: (T, T) -> T,
|
add: (T, T) -> T,
|
||||||
subtract: (T, T) -> T,
|
subtract: (T, T) -> T,
|
||||||
multiply: (T, T) -> T,
|
multiply: (T, T) -> T,
|
||||||
divide: (T, T) -> T
|
divide: (T, T) -> T,
|
||||||
|
euclideanModulo: (T, T) -> T,
|
||||||
|
remainder: (T, T) -> T
|
||||||
): T {
|
): T {
|
||||||
return when (op) {
|
return when (op) {
|
||||||
InfixOperator.Plus -> add(convert(left), convert(right))
|
InfixOperator.Plus -> add(convert(left), convert(right))
|
||||||
InfixOperator.Minus -> subtract(convert(left), convert(right))
|
InfixOperator.Minus -> subtract(convert(left), convert(right))
|
||||||
InfixOperator.Multiply -> multiply(convert(left), convert(right))
|
InfixOperator.Multiply -> multiply(convert(left), convert(right))
|
||||||
InfixOperator.Divide -> divide(convert(left), convert(right))
|
InfixOperator.Divide -> divide(convert(left), convert(right))
|
||||||
|
InfixOperator.EuclideanModulo -> euclideanModulo(convert(left), convert(right))
|
||||||
|
InfixOperator.Remainder -> remainder(convert(left), convert(right))
|
||||||
else -> throw RuntimeException("Unable to handle operation $op")
|
else -> throw RuntimeException("Unable to handle operation $op")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,9 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
TokenType.Multiply,
|
TokenType.Multiply,
|
||||||
TokenType.Divide,
|
TokenType.Divide,
|
||||||
TokenType.Equality,
|
TokenType.Equality,
|
||||||
TokenType.Inequality
|
TokenType.Inequality,
|
||||||
|
TokenType.Mod,
|
||||||
|
TokenType.Rem
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
within {
|
within {
|
||||||
@ -264,6 +266,8 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
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.Rem -> InfixOperator.Remainder
|
||||||
else -> throw RuntimeException("Unknown Infix Operator")
|
else -> throw RuntimeException("Unknown Infix Operator")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
|||||||
LeftParentheses(SingleChar('(')),
|
LeftParentheses(SingleChar('(')),
|
||||||
RightParentheses(SingleChar(')')),
|
RightParentheses(SingleChar(')')),
|
||||||
Negation(SingleChar('!'), Promotion('=', Inequality), OperatorFamily),
|
Negation(SingleChar('!'), Promotion('=', Inequality), OperatorFamily),
|
||||||
|
Mod(Keyword("mod"), OperatorFamily),
|
||||||
|
Rem(Keyword("rem"), OperatorFamily),
|
||||||
Comma(SingleChar(',')),
|
Comma(SingleChar(',')),
|
||||||
Period(SingleChar('.')),
|
Period(SingleChar('.')),
|
||||||
False(Keyword("false"), KeywordFamily),
|
False(Keyword("false"), KeywordFamily),
|
||||||
|
Loading…
Reference in New Issue
Block a user