From c5664f7bd35d8f7a18b2d2d582dfbbae04ad0dda Mon Sep 17 00:00:00 2001 From: Nripesh Niketan Date: Wed, 31 Jul 2024 11:00:31 +0530 Subject: [PATCH] chore: lint --- src/backend/Opengl/OpenglAst.py | 35 +++++--- src/backend/Opengl/OpenglLexer.py | 4 +- src/backend/Opengl/OpenglParser.py | 100 +++++++++++++-------- src/backend/Opengl/__init__.py | 2 +- src/backend/Opengl/openglCrossglCodegen.py | 38 ++++---- 5 files changed, 110 insertions(+), 69 deletions(-) diff --git a/src/backend/Opengl/OpenglAst.py b/src/backend/Opengl/OpenglAst.py index e2f72711..84670a44 100644 --- a/src/backend/Opengl/OpenglAst.py +++ b/src/backend/Opengl/OpenglAst.py @@ -12,7 +12,8 @@ def __repr__(self): def __str__(self): return f"uniform {self.vtype} {self.name};" - + + class ConstantNode(ASTNode): def __init__(self, value): self.value = value @@ -23,9 +24,9 @@ def __repr__(self): def __str__(self): return str(self.value) - + class VersionDirectiveNode(ASTNode): - def __init__(self,number, profile): + def __init__(self, number, profile): self.version_number = number self.profile = profile @@ -35,13 +36,13 @@ def __repr__(self): def __str__(self): return f"#version {self.version_number} {self.profile}" + class LayoutNode: def __init__(self, location_number, dtype, name): self.location_number = location_number self.dtype = dtype self.name = name - def __repr__(self): return f"LayoutNode(location={self.location_number}, dtype={self.dtype})" @@ -57,9 +58,10 @@ def __init__(self, condition, true_expr, false_expr): def __repr__(self): return f"TernaryOpNode(condition={self.condition}, true_expr={self.true_expr}, false_expr={self.false_expr})" - + + class LayoutNode: - def __init__(self,section, location_number, dtype, name): + def __init__(self, section, location_number, dtype, name): self.section = section self.location_number = location_number self.dtype = dtype @@ -69,10 +71,17 @@ def __repr__(self): return f"LayoutNode(section={self.section}, location_number={self.location_number}, dtype={self.dtype}, name={self.name})" - - class ShaderNode: - def __init__(self, version, global_inputs, global_outputs, uniforms, vertex_section, fragment_section, functions): + def __init__( + self, + version, + global_inputs, + global_outputs, + uniforms, + vertex_section, + fragment_section, + functions, + ): self.version = version self.global_inputs = global_inputs self.global_outputs = global_outputs @@ -86,7 +95,7 @@ def __repr__(self): class VERTEXShaderNode: - def __init__(self, inputs, outputs,uniform, functions, layout_qualifiers=[]): + def __init__(self, inputs, outputs, uniform, functions, layout_qualifiers=[]): self.inputs = inputs self.outputs = outputs self.uniform = uniform @@ -98,7 +107,7 @@ def __repr__(self): class FRAGMENTShaderNode: - def __init__(self, inputs, outputs,uniform,functions,layout_qualifiers = []): + def __init__(self, inputs, outputs, uniform, functions, layout_qualifiers=[]): self.inputs = inputs self.outputs = outputs self.uniform = uniform @@ -106,9 +115,7 @@ def __init__(self, inputs, outputs,uniform,functions,layout_qualifiers = []): self.layout_qualifiers = layout_qualifiers def __repr__(self): - return ( - f"FRAGMENTShaderNode({self.inputs!r}) {self.outputs!r}{self.uniform!r} {self.functions!r}{self.layout_qualifiers!r}" - ) + return f"FRAGMENTShaderNode({self.inputs!r}) {self.outputs!r}{self.uniform!r} {self.functions!r}{self.layout_qualifiers!r}" class FunctionNode(ASTNode): diff --git a/src/backend/Opengl/OpenglLexer.py b/src/backend/Opengl/OpenglLexer.py index 8285711c..a63975fb 100644 --- a/src/backend/Opengl/OpenglLexer.py +++ b/src/backend/Opengl/OpenglLexer.py @@ -20,9 +20,9 @@ ("INT", r"int"), ("SAMPLER2D", r"sampler2D"), ("PRE_INCREMENT", r"\+\+(?=\w)"), # Lookahead to match pre-increment - ("PRE_DECREMENT", r"--(?=\w)"), # Lookahead to match pre-decrement + ("PRE_DECREMENT", r"--(?=\w)"), # Lookahead to match pre-decrement ("POST_INCREMENT", r"(?<=\w)\+\+"), # Lookbehind to match post-increment - ("POST_DECREMENT", r"(?<=\w)--"), # Lookbehind to match post-decrement + ("POST_DECREMENT", r"(?<=\w)--"), # Lookbehind to match post-decrement ("IDENTIFIER", r"[a-zA-Z_][a-zA-Z_0-9]*"), ("LBRACE", r"\{"), ("RBRACE", r"\}"), diff --git a/src/backend/Opengl/OpenglParser.py b/src/backend/Opengl/OpenglParser.py index a799af08..5040353b 100644 --- a/src/backend/Opengl/OpenglParser.py +++ b/src/backend/Opengl/OpenglParser.py @@ -19,14 +19,13 @@ ) from .OpenglLexer import Lexer + class Parser: def __init__(self, tokens): self.tokens = tokens self.pos = 0 self.current_token = self.tokens[self.pos] - - def skip_comments(self): while self.current_token[0] in ["COMMENT_MULTI"]: self.eat(self.current_token[0]) @@ -62,41 +61,59 @@ def parse_version_directive(self): self.eat("CORE") return VersionDirectiveNode(number, version_identifier) else: - raise SyntaxError(f"Expected NUMBER after VERSION, got {self.current_token[0]}") + raise SyntaxError( + f"Expected NUMBER after VERSION, got {self.current_token[0]}" + ) else: - raise SyntaxError(f"Expected VERSION directive, got {self.current_token[0]}") + raise SyntaxError( + f"Expected VERSION directive, got {self.current_token[0]}" + ) def parse_layout(self, current_section): self.eat("LAYOUT") self.eat("LPAREN") - - if self.current_token[0] == "IDENTIFIER" and self.current_token[1] == "location": + + if ( + self.current_token[0] == "IDENTIFIER" + and self.current_token[1] == "location" + ): self.eat("IDENTIFIER") self.eat("EQUALS") location_number = self.current_token[1] self.eat("NUMBER") - + self.eat("RPAREN") self.skip_comments() - + if self.current_token[0] == "IN": self.eat("IN") dtype = self.parse_type() name = self.current_token[1] self.eat("IDENTIFIER") self.eat("SEMICOLON") - return LayoutNode(section=current_section, location_number=location_number, dtype=dtype, name=name) + return LayoutNode( + section=current_section, + location_number=location_number, + dtype=dtype, + name=name, + ) elif self.current_token[0] == "OUT": self.eat("OUT") dtype = self.parse_type() name = self.current_token[1] self.eat("IDENTIFIER") self.eat("SEMICOLON") - return LayoutNode(section=current_section, location_number=location_number, dtype=dtype, name=name) + return LayoutNode( + section=current_section, + location_number=location_number, + dtype=dtype, + name=name, + ) else: raise SyntaxError("Expected 'IN' or 'OUT' after location in LAYOUT") else: raise SyntaxError("Expected IDENTIFIER 'location' in LAYOUT") + def parse_shader(self, version_node): global_inputs = [] global_outputs = [] @@ -107,7 +124,9 @@ def parse_shader(self, version_node): while self.current_token[0] != "EOF": if self.current_token[0] == "COMMENT_SINGLE": - comment_content = self.current_token[1].strip().lower() # Normalize content + comment_content = ( + self.current_token[1].strip().lower() + ) # Normalize content print(f"Comment content: '{comment_content}'") if "vertex shader" in comment_content: @@ -119,7 +138,7 @@ def parse_shader(self, version_node): else: current_section = "VERTEX" print("Defaulting to VERTEX section") - + self.eat("COMMENT_SINGLE") if self.current_token[0] == "LAYOUT": @@ -153,7 +172,7 @@ def parse_shader(self, version_node): elif self.current_token[0] == "UNIFORM": self.skip_comments() uniforms.extend(self.parse_uniforms()) - + elif self.current_token[0] == "VERSION": self.parse_version_directive() @@ -189,8 +208,8 @@ def parse_shader(self, version_node): else: raise SyntaxError(f"Unexpected token {self.current_token[0]}") - #print(f"Final vertex section: {vertex_section}") - #print(f"Final fragment section: {fragment_section}") + # print(f"Final vertex section: {vertex_section}") + # print(f"Final fragment section: {fragment_section}") return ShaderNode( version=version_node, @@ -199,7 +218,7 @@ def parse_shader(self, version_node): uniforms=uniforms, vertex_section=vertex_section, fragment_section=fragment_section, - functions=[] + functions=[], ) def parse_shader_section(self, current_section): @@ -220,33 +239,34 @@ def parse_shader_section(self, current_section): elif self.current_token[0] == "IN": self.skip_comments() inputs.extend(self.parse_inputs()) - #print(f"Inputs collected: {inputs}") + # print(f"Inputs collected: {inputs}") elif self.current_token[0] == "OUT": self.skip_comments() outputs.extend(self.parse_outputs()) - #print(f"Outputs collected: {outputs}") + # print(f"Outputs collected: {outputs}") elif self.current_token[0] == "UNIFORM": self.skip_comments() uniforms.extend(self.parse_uniforms()) - #print(f"Uniforms collected: {uniforms}") + # print(f"Uniforms collected: {uniforms}") elif self.current_token[0] in ["VOID", "FLOAT", "VECTOR"]: self.skip_comments() functions.append(self.parse_function()) - #print(f"Functions collected: {functions}") + # print(f"Functions collected: {functions}") elif self.current_token[0] == "RBRACE": self.eat("RBRACE") return (inputs, outputs, uniforms, layout_qualifiers, functions) else: - raise SyntaxError(f"Unexpected token {self.current_token[0]} in shader section") + raise SyntaxError( + f"Unexpected token {self.current_token[0]} in shader section" + ) raise SyntaxError("Unexpected end of input in shader section") - def parse_inputs(self): inputs = [] while self.current_token[0] == "IN": @@ -280,7 +300,6 @@ def parse_uniforms(self): uniforms.append(UniformNode(vtype, name)) return uniforms - def parse_variable(self, type_name): name = self.current_token[1] self.eat("IDENTIFIER") @@ -321,7 +340,7 @@ def parse_variable(self, type_name): raise SyntaxError( f"Unexpected token in variable declaration: {self.current_token[0]}" ) - + def parse_assignment_or_function_call(self): type_name = "" if self.current_token[0] in ["VECTOR", "FLOAT", "INT", "MATRIX"]: @@ -353,7 +372,7 @@ def parse_assignment_or_function_call(self): raise SyntaxError( f"Unexpected token after identifier: {self.current_token[0]}" ) - + def parse_function_call(self, name): self.eat("LPAREN") args = [] @@ -364,7 +383,7 @@ def parse_function_call(self, name): args.append(self.parse_expression()) self.eat("RPAREN") return FunctionCallNode(name, args) - + def parse_function(self): return_type = self.parse_type() if self.current_token[0] == "MAIN": @@ -384,7 +403,7 @@ def parse_function(self): body = self.parse_body() self.eat("RBRACE") return FunctionNode(return_type, fname, params, body) - + def parse_body(self): body = [] while self.current_token[0] not in ["RBRACE", "EOF"]: @@ -419,7 +438,14 @@ def parse_type(self): if self.current_token[0] == "VOID": self.eat("VOID") return "void" - elif self.current_token[0] in ["VECTOR", "FLOAT", "INT", "MATRIX", "BOOLEAN","SAMPLER2D"]: + elif self.current_token[0] in [ + "VECTOR", + "FLOAT", + "INT", + "MATRIX", + "BOOLEAN", + "SAMPLER2D", + ]: dtype = self.current_token[1] self.eat(self.current_token[0]) return dtype @@ -492,6 +518,7 @@ def parse_assignment(self): expr = self.parse_expression() self.eat("SEMICOLON") return AssignmentNode(var_name, expr) + def parse_function_call_or_identifier(self): if self.current_token[0] == "VECTOR": func_name = self.current_token[1] @@ -505,7 +532,7 @@ def parse_function_call_or_identifier(self): elif self.current_token[0] == "DOT": return self.parse_member_access(func_name) return VariableNode("", func_name) - + def parse_additive(self): left = self.parse_multiplicative() while self.current_token[0] in ["PLUS", "MINUS"]: @@ -514,7 +541,7 @@ def parse_additive(self): right = self.parse_multiplicative() left = BinaryOpNode(left, op, right) return left - + def parse_primary(self): if self.current_token[0] == "MINUS": self.eat("MINUS") @@ -571,6 +598,7 @@ def parse_expression(self): left = TernaryOpNode(left, true_expr, false_expr) return left + def parse_return(self): self.eat("RETURN") expr = self.parse_expression() @@ -593,7 +621,7 @@ def parse_if(self): return IfNode(condition, body, else_body) else: return IfNode(condition, body) - + def parse_for(self): self.eat("FOR") self.eat("LPAREN") @@ -606,7 +634,7 @@ def parse_for(self): body = self.parse_body() self.eat("RBRACE") return ForNode(init, condition, update, body) - + def parse_member_access(self, object): self.eat("DOT") if self.current_token[0] != "IDENTIFIER": @@ -650,7 +678,7 @@ def parse_member_access(self, object): } """ - lexer = Lexer(code) + lexer = Lexer(code) parser = Parser(lexer.tokens) for token in lexer.tokens: print(token) @@ -658,6 +686,6 @@ def parse_member_access(self, object): ast = parser.parse() print("Parsing completed successfully!") - #print(ast) - #print("Parsed AST:") - #print(parser.parse()) + # print(ast) + # print("Parsed AST:") + # print(parser.parse()) diff --git a/src/backend/Opengl/__init__.py b/src/backend/Opengl/__init__.py index f15bd200..07805926 100644 --- a/src/backend/Opengl/__init__.py +++ b/src/backend/Opengl/__init__.py @@ -1,3 +1,3 @@ from .OpenglLexer import Lexer from .OpenglParser import Parser -from .openglCrossglCodegen import CrossglCodeGen \ No newline at end of file +from .openglCrossglCodegen import CrossglCodeGen diff --git a/src/backend/Opengl/openglCrossglCodegen.py b/src/backend/Opengl/openglCrossglCodegen.py index ddb502b4..ceeae22c 100644 --- a/src/backend/Opengl/openglCrossglCodegen.py +++ b/src/backend/Opengl/openglCrossglCodegen.py @@ -2,6 +2,7 @@ from .OpenglParser import * from .OpenglLexer import * + class CrossglCodeGen: def __init__(self): self.current_shader = None @@ -41,9 +42,9 @@ def generate_shader(self, node): code += "\n" code += self.generate_uniforms() + "\n" code += "\n" - + # Print the functions to check if they're there - #print(f"Vertex functions: {self.vertex_item.functions}") + # print(f"Vertex functions: {self.vertex_item.functions}") # Generate functions code += self.generate_functions(self.vertex_item.functions, "vertex") @@ -53,7 +54,9 @@ def generate_shader(self, node): # Generate fragment shader section if present self.fragment_item = node.fragment_section - if self.fragment_item and (self.fragment_item.layout_qualifiers or self.fragment_item.functions): + if self.fragment_item and ( + self.fragment_item.layout_qualifiers or self.fragment_item.functions + ): code += " fragment {\n" code += self.generate_layouts(self.fragment_item.layout_qualifiers) # Process inputs and outputs @@ -64,9 +67,9 @@ def generate_shader(self, node): code += "\n" code += self.generate_uniforms() + "\n" code += "\n" - + # Print the functions to check if they're there - # print(f"Fragment functions: {self.fragment_item.functions}") + # print(f"Fragment functions: {self.fragment_item.functions}") # Generate functions code += self.generate_functions(self.fragment_item.functions, "fragment") @@ -84,7 +87,6 @@ def generate_uniforms(self): uniform_lines.append(f" {uniform};") return "\n".join(uniform_lines) - def generate_layouts(self, layouts): code = "" for layout in layouts: @@ -96,7 +98,9 @@ def generate_functions(self, functions, shader_type): if shader_type in ["vertex", "fragment"]: for function_node in functions: - print(f"Function: {function_node.name}, Return Type: {function_node.return_type}, Params: {function_node.params}") + print( + f"Function: {function_node.name}, Return Type: {function_node.return_type}, Params: {function_node.params}" + ) # Generate parameter list params = ", ".join( f"{self.map_type(param[0])} {param[1]}" @@ -112,7 +116,11 @@ def generate_functions(self, functions, shader_type): return code - def generate_statement(self, stmt, indent=0,): + def generate_statement( + self, + stmt, + indent=0, + ): indent_str = " " * indent if isinstance(stmt, VariableNode): return f"{indent_str}{self.map_type(stmt.vtype)} {stmt.name};\n" @@ -180,11 +188,11 @@ def translate_expression(self, expr): def map_type(self, vtype): type_map = { - 'vec3': 'vec3', - 'vec4': 'vec4', - 'float': 'float', - 'int': 'int', - 'bool': 'bool', + "vec3": "vec3", + "vec4": "vec4", + "float": "float", + "int": "int", + "bool": "bool", } return type_map.get(vtype, vtype) @@ -242,9 +250,7 @@ def map_operator(self, op): parser = Parser(lexer.tokens) ast = parser.parse() print("Parsing completed successfully!") - #print(ast) + # print(ast) codegen = CrossglCodeGen() cross_code = codegen.generate(ast) print(cross_code) - -