From 62e95a24ed3da9109f9c48b9a779759918310dbf Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Mon, 1 Sep 2025 07:01:30 +1000 Subject: [PATCH] fixed some scope issues and added label and line reference support to the AST --- ground_ast.py | 37 +++++++++++++++++++++++++++++++++---- test2.grnd | 6 +++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/ground_ast.py b/ground_ast.py index fbf8072..aeaf139 100644 --- a/ground_ast.py +++ b/ground_ast.py @@ -43,6 +43,15 @@ class FunctionNode: parent: FunctionNode | RootNode return_type: Optional[str] = None name: Optional[str] = None +@dataclass +class LabelDecNode: + name: str +@dataclass +class LabelRefNode: + name: str +@dataclass +class LineRefNode: + line: int def generate_ast(tokens: list[Token], code: str) -> RootNode: root_node = RootNode([]) @@ -55,7 +64,7 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: # todo: this is the absolute WORST way i could do this, but i could not care less lmao # its not even performant...... for token in tokens: - print(token) + #print(token.type) if token.type == TokenType.INSTRUCTION: if current_node: scope.statements.append(current_node) @@ -68,9 +77,15 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: current_node_type = "inst" if current_node.instruction == "endfun": - scope = scope.parent # go up one scope + if scope == root_node: + traceback(code, "ScopeError", "You can't use endfun from global scope, did you mean to use the \"end\" instruction?") - current_node.parent = scope + scope = scope.parent # go up one scope + current_node.parent = scope + scope.statements.append(current_node) + current_node = scope + else: + current_node.parent = scope else: current_node = FunctionNode([], [], scope) current_node_type = "func" @@ -88,11 +103,22 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: else: traceback(code, "SyntaxError", "Expected instruction, not number.") + elif token.type == TokenType.LINE_REFERENCE: + if current_node_type == "inst": + current_node.arguments.append(LineRefNode(token.value)) + else: + traceback(code, "SyntaxError", "Expected instruction, not line reference") + + elif token.type == TokenType.LABEL_REFERENCE: + if current_node_type == "inst": + current_node.arguments.append(LabelRefNode(token.value)) + else: + traceback(code, "SyntaxError", "Expected instruction, not label reference") + elif token.type == TokenType.VARIABLE_POINTER: if current_node_type == "inst": current_node.arguments.append(VarPointerNode(token.value)) elif last_token and last_token.type == TokenType.TYPE and current_node_type == "func": - print(current_node) current_node.args[-1].name = token.value else: traceback(code, "SyntaxError", "Expected instruction, not variable pointer.") @@ -126,6 +152,9 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: else: traceback(code, "SyntaxError", "Expected instruction or function return type, got function reference.") + elif token.type == TokenType.LABEL_DECLERATION: + scope.statements.append(LabelDecNode(token.value)) + elif token.type == TokenType.EOF: root_node.statements.append(current_node) last_token = token diff --git a/test2.grnd b/test2.grnd index 79d3f11..8f002a5 100644 --- a/test2.grnd +++ b/test2.grnd @@ -5,8 +5,8 @@ fun -list !split -string &str -string &determiner set &x 2 set &y 5 add $x $y &x -stdlnout $x +return $x endfun -# should error -stdlnout $x \ No newline at end of file +@myLabel +jump %myLabel \ No newline at end of file