aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Yakimowich-Payne <jyapayne@gmail.com>2020-04-23 16:45:19 -0600
committerJoey Yakimowich-Payne <jyapayne@gmail.com>2020-04-26 09:11:56 -0600
commit2813dc61f22aecaaaa82054f144a48c4de520cf2 (patch)
tree3b072149d8e4c5ee7d8a90e5d378b43576fe85b6
parentc0977fa8271f462c20a29f4bb0976c638a534b45 (diff)
downloadnimterop-2813dc61f22aecaaaa82054f144a48c4de520cf2.tar.gz
nimterop-2813dc61f22aecaaaa82054f144a48c4de520cf2.zip
Consolidate shift_expression into binary_expression and write more tests
-rw-r--r--nimterop/exprparser.nim91
-rw-r--r--tests/include/tast2.h10
-rw-r--r--tests/tast2.nim14
3 files changed, 42 insertions, 73 deletions
diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim
index 7acb375..a59a546 100644
--- a/nimterop/exprparser.nim
+++ b/nimterop/exprparser.nim
@@ -232,61 +232,6 @@ proc processStringLiteral(gState: State, node: TSNode): PNode =
proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode
-proc processShiftExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode =
- # Input => a >> b
- #
- # (shift_expression 1 2 6
- # (identifier 1 2 1 "a")
- # (identifier 1 7 1 "b")
- # )
- #
- # Output => a shr typeof(a)(b)
- #
- # nkInfix(
- # nkIdent("shr"),
- # nkIdent("a"),
- # nkCall(
- # nkCall(
- # nkIdent("typeof"),
- # nkIdent("a")
- # ),
- # nkIdent("b")
- # )
- # )
- result = newNode(nkInfix)
- let
- left = node[0]
- right = node[1]
-
- let shiftSym = node.tsNodeChild(1).val.strip()
-
- case shiftSym
- of "<<":
- result.add gState.getIdent("shl")
- of ">>":
- result.add gState.getIdent("shr")
- else:
- raise newException(ExprParseError, &"Unsupported shift symbol \"{shiftSym}\"")
-
- let leftNode = gState.processTSNode(left, typeofNode)
-
- # If the typeofNode is nil, set it
- # to be the leftNode because C's type coercion
- # happens left to right, and we want to emulate it
- if typeofNode.isNil:
- typeofNode = nkCall.newTree(
- gState.getIdent("typeof"),
- leftNode
- )
-
- let rightNode = gState.processTSNode(right, typeofNode)
-
- result.add leftNode
- result.add nkCall.newTree(
- typeofNode,
- rightNode
- )
-
proc processParenthesizedExpr(gState: State, node: TSNode, typeofNode: var PNode): PNode =
# Input => (a + b)
#
@@ -369,6 +314,10 @@ proc getNimBinarySym(csymbol: string): string =
result = csymbol
of "%":
result = "mod"
+ of "<<":
+ result = "shl"
+ of ">>":
+ result = "shr"
else:
raise newException(ExprParseError, &"Unsupported binary symbol \"{csymbol}\"")
@@ -419,6 +368,15 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode)
typeofNode,
rightNode
)
+ if binarySym == "/":
+ # Special case. Nim's operators generally output
+ # the same type they take in, except for division.
+ # So we need to emulate C here and cast the whole
+ # expression to the type of the first arg
+ result = nkCall.newTree(
+ typeofNode,
+ result
+ )
proc processUnaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode =
# Input => !a
@@ -469,17 +427,7 @@ proc processUnaryOrBinaryExpression(gState: State, node: TSNode, typeofNode: var
## Processes both unary (-1, ~true, !something) and binary (a + b, c * d) expressions
if node.len > 1:
# Node has left and right children ie: (2 + 7)
-
- # Make sure the statement is of the same type as the left
- # hand argument, since some expressions return a differing
- # type than the input types (2/3 == float)
- let binExpr = processBinaryExpression(gState, node, typeofNode)
- # Note that this temp var binExpr is needed for some reason, or else we get a segfault
- result = nkCall.newTree(
- typeofNode,
- binexpr
- )
-
+ result = processBinaryExpression(gState, node, typeofNode)
elif node.len() == 1:
# Node has only one child, ie -(20 + 7)
result = processUnaryExpression(gState, node, typeofNode)
@@ -553,8 +501,9 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode =
# binary_expression from the new treesitter upgrade should work here
# once we upgrade
of "math_expression", "logical_expression", "relational_expression",
- "bitwise_expression", "equality_expression", "binary_expression":
- # Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b
+ "bitwise_expression", "equality_expression", "binary_expression",
+ "shift_expression":
+ # Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b, a >> b, a << b
# Output ->
# typeof(a)(a == typeof(a)(b))
# typeof(a)(a != typeof(a)(b))
@@ -564,11 +513,9 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode =
# typeof(a)(a > typeof(a)(b))
# typeof(a)(a <= typeof(a)(b))
# typeof(a)(a >= typeof(a)(b))
+ # a shr typeof(a)(b)
+ # a shl typeof(a)(b)
result = gState.processUnaryOrBinaryExpression(node, typeofNode)
- of "shift_expression":
- # Input -> a >> b, a << b
- # Output -> a shr typeof(a)(b), a shl typeof(a)(b)
- result = gState.processShiftExpression(node, typeofNode)
of "cast_expression":
# Input -> (int) a
# Output -> cast[cint](a)
diff --git a/tests/include/tast2.h b/tests/include/tast2.h
index 53b4d64..e72a3b8 100644
--- a/tests/include/tast2.h
+++ b/tests/include/tast2.h
@@ -24,6 +24,16 @@ extern "C" {
#define MATHEXPR (1 + 2/3*20 - 100)
#define ANDEXPR (100 & 11000)
#define CASTEXPR (char) 34
+#define a 100
+#define b 200
+#define EQ1 a <= b
+#define EQ2 a >= b
+#define EQ3 a > b
+#define EQ4 a < b
+#define EQ5 a != b
+#define EQ6 a == b
+
+#define SIZEOF sizeof(char)
#define NULLCHAR '\0'
#define OCTCHAR '\012'
diff --git a/tests/tast2.nim b/tests/tast2.nim
index e82430b..57bfc90 100644
--- a/tests/tast2.nim
+++ b/tests/tast2.nim
@@ -115,6 +115,18 @@ assert ULLEXPR == (1234.uint64 shl 3)
assert LEXPR == (1234.int32 shl 4)
assert LLEXPR == (1234.int64 shl 5)
+assert a == 100
+assert b == 200
+
+assert EQ1 == (a <= b)
+assert EQ2 == (a >= b)
+assert EQ3 == (a > b)
+assert EQ4 == (a < b)
+assert EQ5 == (a != b)
+assert EQ6 == (a == b)
+
+assert SIZEOF == 1
+
assert COERCE == 645635670332'u64
assert COERCE2 == 645635670332'i64
@@ -303,7 +315,7 @@ var a21p: A21p
a21p = addr a20
assert A22 is object
-testFields(A22, "f1|f2!ptr ptr cint|array[type(123)(255), ptr cint]")
+testFields(A22, "f1|f2!ptr ptr cint|array[123 + type(123)(132), ptr cint]")
checkPragmas(A22, pHeaderBy, istype = false)
var a22: A22
a22.f1 = addr a15.a2[0]