diff options
| author | Joey Yakimowich-Payne <jyapayne@gmail.com> | 2020-04-23 16:45:19 -0600 |
|---|---|---|
| committer | Joey Yakimowich-Payne <jyapayne@gmail.com> | 2020-04-26 09:11:56 -0600 |
| commit | 2813dc61f22aecaaaa82054f144a48c4de520cf2 (patch) | |
| tree | 3b072149d8e4c5ee7d8a90e5d378b43576fe85b6 | |
| parent | c0977fa8271f462c20a29f4bb0976c638a534b45 (diff) | |
| download | nimterop-2813dc61f22aecaaaa82054f144a48c4de520cf2.tar.gz nimterop-2813dc61f22aecaaaa82054f144a48c4de520cf2.zip | |
Consolidate shift_expression into binary_expression and write more tests
| -rw-r--r-- | nimterop/exprparser.nim | 91 | ||||
| -rw-r--r-- | tests/include/tast2.h | 10 | ||||
| -rw-r--r-- | tests/tast2.nim | 14 |
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] |
