Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bitwise not operator support with tests #259

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crosstl/backend/DirectX/DirectxLexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
[
("COMMENT_SINGLE", r"//.*"),
("COMMENT_MULTI", r"/\*[\s\S]*?\*/"),
("BITWISE_NOT", r"~"),
("INCLUDE", r"\#include\b"),
("STRUCT", r"\bstruct\b"),
("CBUFFER", r"\bcbuffer\b"),
Expand Down
2 changes: 1 addition & 1 deletion crosstl/backend/DirectX/DirectxParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ def parse_multiplicative(self):
return left

def parse_unary(self):
if self.current_token[0] in ["PLUS", "MINUS"]:
if self.current_token[0] in ["PLUS", "MINUS", "BITWISE_NOT"]:
op = self.current_token[1]
self.eat(self.current_token[0])
operand = self.parse_unary()
Expand Down
1 change: 1 addition & 0 deletions crosstl/backend/Metal/MetalLexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[
("COMMENT_SINGLE", r"//.*"),
("COMMENT_MULTI", r"/\*[\s\S]*?\*/"),
("BITWISE_NOT", r"~"),
("PREPROCESSOR", r"#\w+"),
("STRUCT", r"\bstruct\b"),
("CONSTANT", r"\bconstant\b"),
Expand Down
2 changes: 1 addition & 1 deletion crosstl/backend/Metal/MetalParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ def parse_multiplicative(self):
return left

def parse_unary(self):
if self.current_token[0] in ["PLUS", "MINUS"]:
if self.current_token[0] in ["PLUS", "MINUS", "BITWISE_NOT"]:
op = self.current_token[1]
self.eat(self.current_token[0])
operand = self.parse_unary()
Expand Down
1 change: 1 addition & 0 deletions crosstl/backend/Mojo/MojoLexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[
("COMMENT_SINGLE", r"#.*"),
("COMMENT_MULTI", r'"""[\s\S]*?"""'),
("BITWISE_NOT", r"~"),
("STRUCT", r"\bstruct\b"),
("LET", r"\blet\b"),
("VAR", r"\bvar\b"),
Expand Down
2 changes: 1 addition & 1 deletion crosstl/backend/Mojo/MojoParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ def parse_multiplicative(self):
return left

def parse_unary(self):
if self.current_token[0] in ["PLUS", "MINUS"]:
if self.current_token[0] in ["PLUS", "MINUS", "BITWISE_NOT"]:
op = self.current_token[1]
self.eat(self.current_token[0])
operand = self.parse_unary()
Expand Down
10 changes: 5 additions & 5 deletions crosstl/backend/Opengl/OpenglParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,11 +729,11 @@ def parse_unary(self):
ASTNode: An ASTNode object representing the unary expression

"""
if self.current_token[0] in ["PLUS", "MINUS"]:
op = self.current_token[0]
self.eat(op)
expr = self.parse_unary()
return UnaryOpNode(op, expr)
if self.current_token[0] in ["PLUS", "MINUS", "BITWISE_NOT"]:
op = self.current_token[1]
self.eat(self.current_token[0])
operand = self.parse_unary()
return UnaryOpNode(op, operand)
return self.parse_primary()

def parse_primary(self):
Expand Down
1 change: 1 addition & 0 deletions crosstl/backend/Vulkan/VulkanLexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[
("COMMENT_SINGLE", r"//.*"),
("COMMENT_MULTI", r"/\*[\s\S]*?\*/"),
("BITWISE_NOT", r"~"),
("WHITESPACE", r"\s+"),
("SEMANTIC", r":\w+"),
("PRE_INCREMENT", r"\+\+(?=\w)"),
Expand Down
13 changes: 13 additions & 0 deletions crosstl/backend/Vulkan/VulkanParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ def parse_primary(self):
value = self.parse_primary()
return UnaryOpNode("-", value)

if self.current_token[0] == "BITWISE_NOT":
self.eat("BITWISE_NOT")
value = self.parse_primary()
return UnaryOpNode("~", value)

if (
self.current_token[0] == "IDENTIFIER"
or self.current_token[1] in VALID_DATA_TYPES
Expand Down Expand Up @@ -663,3 +668,11 @@ def parse_uniform(self):
self.eat("IDENTIFIER")
self.eat("SEMICOLON")
return UniformNode(name, var_type)

def parse_unary(self):
if self.current_token[0] in ["PLUS", "MINUS", "BITWISE_NOT"]:
op = self.current_token[1]
self.eat(self.current_token[0])
operand = self.parse_unary()
return UnaryOpNode(op, operand)
return self.parse_primary()
1 change: 1 addition & 0 deletions crosstl/backend/slang/SlangLexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
[
("COMMENT_SINGLE", r"//.*"),
("COMMENT_MULTI", r"/\*[\s\S]*?\*/"),
("BITWISE_NOT", r"~"),
("STRUCT", r"\bstruct\b"),
("CBUFFER", r"\bcbuffer\b"),
("TYPE_SHADER", r'\[shader\("(vertex|fragment|compute)"\)\]'),
Expand Down
2 changes: 1 addition & 1 deletion crosstl/backend/slang/SlangParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ def parse_multiplicative(self):
return left

def parse_unary(self):
if self.current_token[0] in ["PLUS", "MINUS"]:
if self.current_token[0] in ["PLUS", "MINUS", "BITWISE_NOT"]:
op = self.current_token[1]
self.eat(self.current_token[0])
operand = self.parse_unary()
Expand Down
1 change: 1 addition & 0 deletions crosstl/translator/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
("COMMENT_SINGLE", r"//.*"),
("COMMENT_MULTI", r"/\*[\s\S]*?\*/"),
("SHADER", r"\bshader\b"),
("BITWISE_NOT", r"~"),
("VOID", r"\bvoid\b"),
("STRUCT", r"\bstruct\b"),
("CBUFFER", r"\bcbuffer\b"),
Expand Down
4 changes: 1 addition & 3 deletions crosstl/translator/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,11 +690,9 @@ def parse_unary(self):
This method parses a unary expression in the shader code.

Returns:

ASTNode: An ASTNode object representing the unary expression

"""
if self.current_token[0] in ["PLUS", "MINUS"]:
if self.current_token[0] in ["PLUS", "MINUS", "BITWISE_NOT"]:
op = self.current_token[0]
self.eat(op)
expr = self.parse_unary()
Expand Down
16 changes: 16 additions & 0 deletions tests/test_backend/test_directx/test_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,5 +718,21 @@ def test_half_dtype_codegen():
pytest.fail("half dtype parsing or code generation not implemented.")


def test_bitwise_not_codegen():
code = """
void main() {
int a = 5;
int b = ~a; // Bitwise NOT
}
"""
try:
tokens = tokenize_code(code)
ast = parse_code(tokens)
generated_code = generate_code(ast)
print(generated_code)
except SyntaxError:
pytest.fail("Bitwise NOT operator code generation not implemented")


if __name__ == "__main__":
pytest.main()
15 changes: 15 additions & 0 deletions tests/test_backend/test_directx/test_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,5 +299,20 @@ def test_half_dtype_tokenization():
pytest.fail("half dtype tokenization is not implemented.")


def test_bitwise_not_tokenization():
code = """
int a = ~5; // Bitwise NOT
"""
tokens = tokenize_code(code)

has_not = False
for token in tokens:
if token == ("BITWISE_NOT", "~"):
has_not = True
break

assert has_not, "Bitwise NOT operator (~) not tokenized correctly"


if __name__ == "__main__":
pytest.main()
14 changes: 14 additions & 0 deletions tests/test_backend/test_directx/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,5 +415,19 @@ def test_double_dtype_parsing():
pytest.fail("half dtype not implemented.")


def test_bitwise_not_parsing():
code = """
void main() {
int a = 5;
int b = ~a; // Bitwise NOT
}
"""
try:
tokens = tokenize_code(code)
parse_code(tokens)
except SyntaxError:
pytest.fail("Bitwise NOT operator parsing not implemented")


if __name__ == "__main__":
pytest.main()
16 changes: 16 additions & 0 deletions tests/test_backend/test_metal/test_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,5 +331,21 @@ def test_else_if():
print(generated_code)


def test_bitwise_not_codegen():
code = """
void main() {
int a = 5;
int b = ~a; // Bitwise NOT
}
"""
try:
tokens = tokenize_code(code)
ast = parse_code(tokens)
generated_code = generate_code(ast)
print(generated_code)
except SyntaxError:
pytest.fail("Bitwise NOT operator code generation not implemented")


if __name__ == "__main__":
pytest.main()
15 changes: 15 additions & 0 deletions tests/test_backend/test_metal/test_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,20 @@ def test_mod_tokenization():
assert has_mod, "Modulus operator (%) not tokenized correctly"


def test_bitwise_not_tokenization():
code = """
int a = ~5; // Bitwise NOT
"""
tokens = tokenize_code(code)

has_not = False
for token in tokens:
if token == ("BITWISE_NOT", "~"):
has_not = True
break

assert has_not, "Bitwise NOT operator (~) not tokenized correctly"


if __name__ == "__main__":
pytest.main()
14 changes: 14 additions & 0 deletions tests/test_backend/test_metal/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,19 @@ def test_mod_parsing():
pytest.fail("Modulus operator parsing not implemented")


def test_bitwise_not_parsing():
code = """
void main() {
int a = 5;
int b = ~a; // Bitwise NOT
}
"""
try:
tokens = tokenize_code(code)
parse_code(tokens)
except SyntaxError:
pytest.fail("Bitwise NOT operator parsing not implemented")


if __name__ == "__main__":
pytest.main()
13 changes: 13 additions & 0 deletions tests/test_backend/test_mojo/test_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,18 @@ def test_mod_tokenization():
assert has_mod, "Modulus operator (%) not tokenized correctly"


def test_bitwise_not_tokenization():
code = """
int a = ~5; // Bitwise NOT
"""
tokens = tokenize_code(code)
has_not = False
for token in tokens:
if token == ("BITWISE_NOT", "~"):
has_not = True
break
assert has_not, "Bitwise NOT operator (~) not tokenized correctly"


if __name__ == "__main__":
pytest.main()
16 changes: 13 additions & 3 deletions tests/test_backend/test_opengl/test_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,27 @@ def test_mod_tokenization():
int a = 10 % 3; // Basic modulus
"""
tokens = tokenize_code(code)

# Find the modulus operator in tokens
has_mod = False
for token in tokens:
if token == ("MOD", "%"):
has_mod = True
break

assert has_mod, "Modulus operator (%) not tokenized correctly"


def test_bitwise_not_tokenization():
code = """
int a = ~5; // Bitwise NOT
"""
tokens = tokenize_code(code)
has_not = False
for token in tokens:
if token == ("BITWISE_NOT", "~"):
has_not = True
break
assert has_not, "Bitwise NOT operator (~) not tokenized correctly"


def test_unsigned_int_dtype_tokenization():
code = """
double ComputeArea(double radius) {
Expand Down
16 changes: 13 additions & 3 deletions tests/test_backend/test_slang/test_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,26 @@ def test_mod_tokenization():
int a = 10 % 3; // Basic modulus
"""
tokens = tokenize_code(code)

# Find the modulus operator in tokens
has_mod = False
for token in tokens:
if token == ("MOD", "%"):
has_mod = True
break

assert has_mod, "Modulus operator (%) not tokenized correctly"


def test_bitwise_not_tokenization():
code = """
int a = ~5; // Bitwise NOT
"""
tokens = tokenize_code(code)
has_not = False
for token in tokens:
if token == ("BITWISE_NOT", "~"):
has_not = True
break
assert has_not, "Bitwise NOT operator (~) not tokenized correctly"


if __name__ == "__main__":
pytest.main()
13 changes: 13 additions & 0 deletions tests/test_backend/test_vulkan/test_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,18 @@ def test_mod_tokenization():
assert has_mod, "Modulus operator (%) not tokenized correctly"


def test_bitwise_not_tokenization():
code = """
int a = ~5; // Bitwise NOT
"""
tokens = tokenize_code(code)
has_not = False
for token in tokens:
if token == ("BITWISE_NOT", "~"):
has_not = True
break
assert has_not, "Bitwise NOT operator (~) not tokenized correctly"


if __name__ == "__main__":
pytest.main()
14 changes: 14 additions & 0 deletions tests/test_backend/test_vulkan/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,19 @@ def test_mod_parsing():
pytest.fail("Modulus operator parsing not implemented")


def test_bitwise_not_parsing():
code = """
void main() {
int a = 5;
int b = ~a; // Bitwise NOT
}
"""
try:
tokens = tokenize_code(code)
parse_code(tokens)
except SyntaxError:
pytest.fail("Bitwise NOT operator parsing not implemented")


if __name__ == "__main__":
pytest.main()
Loading
Loading