fixed some scope issues and added label and line reference support to the AST

This commit is contained in:
SpookyDervish
2025-09-01 07:01:30 +10:00
parent eee9325ab8
commit 62e95a24ed
2 changed files with 36 additions and 7 deletions

View File

@@ -43,6 +43,15 @@ class FunctionNode:
parent: FunctionNode | RootNode parent: FunctionNode | RootNode
return_type: Optional[str] = None return_type: Optional[str] = None
name: 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: def generate_ast(tokens: list[Token], code: str) -> RootNode:
root_node = 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 # todo: this is the absolute WORST way i could do this, but i could not care less lmao
# its not even performant...... # its not even performant......
for token in tokens: for token in tokens:
print(token) #print(token.type)
if token.type == TokenType.INSTRUCTION: if token.type == TokenType.INSTRUCTION:
if current_node: if current_node:
scope.statements.append(current_node) scope.statements.append(current_node)
@@ -68,9 +77,15 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
current_node_type = "inst" current_node_type = "inst"
if current_node.instruction == "endfun": 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: else:
current_node = FunctionNode([], [], scope) current_node = FunctionNode([], [], scope)
current_node_type = "func" current_node_type = "func"
@@ -88,11 +103,22 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
else: else:
traceback(code, "SyntaxError", "Expected instruction, not number.") 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: elif token.type == TokenType.VARIABLE_POINTER:
if current_node_type == "inst": if current_node_type == "inst":
current_node.arguments.append(VarPointerNode(token.value)) current_node.arguments.append(VarPointerNode(token.value))
elif last_token and last_token.type == TokenType.TYPE and current_node_type == "func": elif last_token and last_token.type == TokenType.TYPE and current_node_type == "func":
print(current_node)
current_node.args[-1].name = token.value current_node.args[-1].name = token.value
else: else:
traceback(code, "SyntaxError", "Expected instruction, not variable pointer.") traceback(code, "SyntaxError", "Expected instruction, not variable pointer.")
@@ -126,6 +152,9 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
else: else:
traceback(code, "SyntaxError", "Expected instruction or function return type, got function reference.") 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: elif token.type == TokenType.EOF:
root_node.statements.append(current_node) root_node.statements.append(current_node)
last_token = token last_token = token

View File

@@ -5,8 +5,8 @@ fun -list !split -string &str -string &determiner
set &x 2 set &x 2
set &y 5 set &y 5
add $x $y &x add $x $y &x
stdlnout $x return $x
endfun endfun
# should error @myLabel
stdlnout $x jump %myLabel