Consolidate shift_expression into binary_expression and write more tests
This commit is contained in:
parent
619421ba85
commit
fafdc42876
3 changed files with 42 additions and 73 deletions
|
|
@ -232,61 +232,6 @@ proc processStringLiteral(gState: State, node: TSNode): PNode =
|
||||||
|
|
||||||
proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): 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 =
|
proc processParenthesizedExpr(gState: State, node: TSNode, typeofNode: var PNode): PNode =
|
||||||
# Input => (a + b)
|
# Input => (a + b)
|
||||||
#
|
#
|
||||||
|
|
@ -369,6 +314,10 @@ proc getNimBinarySym(csymbol: string): string =
|
||||||
result = csymbol
|
result = csymbol
|
||||||
of "%":
|
of "%":
|
||||||
result = "mod"
|
result = "mod"
|
||||||
|
of "<<":
|
||||||
|
result = "shl"
|
||||||
|
of ">>":
|
||||||
|
result = "shr"
|
||||||
else:
|
else:
|
||||||
raise newException(ExprParseError, &"Unsupported binary symbol \"{csymbol}\"")
|
raise newException(ExprParseError, &"Unsupported binary symbol \"{csymbol}\"")
|
||||||
|
|
||||||
|
|
@ -419,6 +368,15 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode)
|
||||||
typeofNode,
|
typeofNode,
|
||||||
rightNode
|
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 =
|
proc processUnaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode =
|
||||||
# Input => !a
|
# 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
|
## Processes both unary (-1, ~true, !something) and binary (a + b, c * d) expressions
|
||||||
if node.len > 1:
|
if node.len > 1:
|
||||||
# Node has left and right children ie: (2 + 7)
|
# Node has left and right children ie: (2 + 7)
|
||||||
|
result = processBinaryExpression(gState, node, typeofNode)
|
||||||
# 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
|
|
||||||
)
|
|
||||||
|
|
||||||
elif node.len() == 1:
|
elif node.len() == 1:
|
||||||
# Node has only one child, ie -(20 + 7)
|
# Node has only one child, ie -(20 + 7)
|
||||||
result = processUnaryExpression(gState, node, typeofNode)
|
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
|
# binary_expression from the new treesitter upgrade should work here
|
||||||
# once we upgrade
|
# once we upgrade
|
||||||
of "math_expression", "logical_expression", "relational_expression",
|
of "math_expression", "logical_expression", "relational_expression",
|
||||||
"bitwise_expression", "equality_expression", "binary_expression":
|
"bitwise_expression", "equality_expression", "binary_expression",
|
||||||
# Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b
|
"shift_expression":
|
||||||
|
# Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b, a >> b, a << b
|
||||||
# Output ->
|
# Output ->
|
||||||
# typeof(a)(a == typeof(a)(b))
|
# typeof(a)(a == typeof(a)(b))
|
||||||
# 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))
|
# 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)
|
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":
|
of "cast_expression":
|
||||||
# Input -> (int) a
|
# Input -> (int) a
|
||||||
# Output -> cast[cint](a)
|
# Output -> cast[cint](a)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,16 @@ extern "C" {
|
||||||
#define MATHEXPR (1 + 2/3*20 - 100)
|
#define MATHEXPR (1 + 2/3*20 - 100)
|
||||||
#define ANDEXPR (100 & 11000)
|
#define ANDEXPR (100 & 11000)
|
||||||
#define CASTEXPR (char) 34
|
#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 NULLCHAR '\0'
|
||||||
#define OCTCHAR '\012'
|
#define OCTCHAR '\012'
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,18 @@ assert ULLEXPR == (1234.uint64 shl 3)
|
||||||
assert LEXPR == (1234.int32 shl 4)
|
assert LEXPR == (1234.int32 shl 4)
|
||||||
assert LLEXPR == (1234.int64 shl 5)
|
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 COERCE == 645635670332'u64
|
||||||
assert COERCE2 == 645635670332'i64
|
assert COERCE2 == 645635670332'i64
|
||||||
|
|
||||||
|
|
@ -303,7 +315,7 @@ var a21p: A21p
|
||||||
a21p = addr a20
|
a21p = addr a20
|
||||||
|
|
||||||
assert A22 is object
|
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)
|
checkPragmas(A22, pHeaderBy, istype = false)
|
||||||
var a22: A22
|
var a22: A22
|
||||||
a22.f1 = addr a15.a2[0]
|
a22.f1 = addr a15.a2[0]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue