mirror of
https://github.com/Zandercraft/Aurora-lang.git
synced 2026-10-29 04:39:21 +00:00
Moved all AST nodes to a separate module and fixed a bug with unary + operator
This commit is contained in:
164
aurora.py
164
aurora.py
@@ -12,6 +12,7 @@ Purpose: Main implementation of Aurora
|
|||||||
# Imports
|
# Imports
|
||||||
import string
|
import string
|
||||||
from exceptions import core as exceptions
|
from exceptions import core as exceptions
|
||||||
|
from internal import nodes
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# CONSTANTS
|
# CONSTANTS
|
||||||
@@ -21,12 +22,6 @@ LETTERS = string.ascii_letters
|
|||||||
LETTERS_DIGITS = LETTERS + DIGITS
|
LETTERS_DIGITS = LETTERS + DIGITS
|
||||||
|
|
||||||
|
|
||||||
####################
|
|
||||||
# ERRORS
|
|
||||||
####################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# POSITION
|
# POSITION
|
||||||
####################
|
####################
|
||||||
@@ -311,119 +306,6 @@ class Lexer:
|
|||||||
return Token(token_type, pos_start=pos_start, pos_end=self.pos)
|
return Token(token_type, pos_start=pos_start, pos_end=self.pos)
|
||||||
|
|
||||||
|
|
||||||
####################
|
|
||||||
# NODES
|
|
||||||
####################
|
|
||||||
class NumberNode:
|
|
||||||
def __init__(self, token):
|
|
||||||
self.token = token
|
|
||||||
self.pos_start = self.token.pos_start
|
|
||||||
self.pos_end = self.token.pos_end
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"{self.token}"
|
|
||||||
|
|
||||||
|
|
||||||
class StringNode:
|
|
||||||
def __init__(self, token):
|
|
||||||
self.token = token
|
|
||||||
self.pos_start = self.token.pos_start
|
|
||||||
self.pos_end = self.token.pos_end
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f'{self.token}'
|
|
||||||
|
|
||||||
|
|
||||||
class VarAccessNode:
|
|
||||||
def __init__(self, var_name_token):
|
|
||||||
self.var_name_token = var_name_token
|
|
||||||
self.pos_start = self.var_name_token.pos_start
|
|
||||||
self.pos_end = self.var_name_token.pos_end
|
|
||||||
|
|
||||||
|
|
||||||
class VarAssignNode:
|
|
||||||
def __init__(self, var_name_token, value_node):
|
|
||||||
self.var_name_token = var_name_token
|
|
||||||
self.value_node = value_node
|
|
||||||
self.pos_start = self.var_name_token.pos_start
|
|
||||||
self.pos_end = self.var_name_token.pos_end
|
|
||||||
|
|
||||||
|
|
||||||
class BinaryOperationNode:
|
|
||||||
def __init__(self, left_node, operation, right_node):
|
|
||||||
self.left_node = left_node
|
|
||||||
self.operation = operation
|
|
||||||
self.right_node = right_node
|
|
||||||
self.pos_start = self.left_node.pos_start
|
|
||||||
self.pos_end = self.right_node.pos_end
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"({self.left_node}, {self.operation}, {self.right_node})"
|
|
||||||
|
|
||||||
|
|
||||||
class UnaryOperationNode:
|
|
||||||
def __init__(self, operation, node):
|
|
||||||
self.operation = operation
|
|
||||||
self.node = node
|
|
||||||
self.pos_start = self.operation.pos_start
|
|
||||||
self.pos_end = self.node.pos_end
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f'({self.operation}, {self.node})'
|
|
||||||
|
|
||||||
|
|
||||||
class IfNode:
|
|
||||||
def __init__(self, cases, else_case):
|
|
||||||
self.cases = cases
|
|
||||||
self.else_case = else_case
|
|
||||||
self.pos_start = self.cases[0][0].pos_start
|
|
||||||
self.pos_end = (self.else_case or self.cases[len(self.cases) - 1][0]).pos_end
|
|
||||||
|
|
||||||
|
|
||||||
class ForNode:
|
|
||||||
def __init__(self, var_name_token, start_value_node, end_value_node, step_value_node, body_node):
|
|
||||||
self.var_name_token = var_name_token
|
|
||||||
self.start_value_node = start_value_node
|
|
||||||
self.end_value_node = end_value_node
|
|
||||||
self.step_value_node = step_value_node
|
|
||||||
self.body_node = body_node
|
|
||||||
self.pos_start = self.var_name_token.pos_start
|
|
||||||
self.pos_end = self.body_node.pos_end
|
|
||||||
|
|
||||||
|
|
||||||
class WhileNode:
|
|
||||||
def __init__(self, condition_node, body_node):
|
|
||||||
self.condition_node = condition_node
|
|
||||||
self.body_node = body_node
|
|
||||||
self.pos_start = condition_node.pos_start
|
|
||||||
self.pos_end = body_node.pos_end
|
|
||||||
|
|
||||||
|
|
||||||
class FunDefNode:
|
|
||||||
def __init__(self, var_name_token, arg_name_tokens, body_node):
|
|
||||||
self.var_name_token = var_name_token
|
|
||||||
self.arg_name_tokens = arg_name_tokens
|
|
||||||
self.body_node = body_node
|
|
||||||
if self.var_name_token:
|
|
||||||
self.pos_start = self.var_name_token.pos_start
|
|
||||||
elif len(self.arg_name_tokens) > 0:
|
|
||||||
self.pos_start = self.arg_name_tokens[0].pos_start
|
|
||||||
else:
|
|
||||||
self.pos_start = self.body_node.pos_start
|
|
||||||
self.pos_end = self.body_node.pos_end
|
|
||||||
|
|
||||||
|
|
||||||
class CallNode:
|
|
||||||
def __init__(self, node_to_call, arg_nodes):
|
|
||||||
self.node_to_call = node_to_call
|
|
||||||
self.arg_nodes = arg_nodes
|
|
||||||
self.pos_start = self.node_to_call.pos_start
|
|
||||||
if len(self.arg_nodes) > 0:
|
|
||||||
self.pos_end = self.arg_nodes[len(self.arg_nodes) - 1].pos_end
|
|
||||||
else:
|
|
||||||
self.pos_end = self.node_to_call.pos_end
|
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# PARSER RESULT
|
# PARSER RESULT
|
||||||
####################
|
####################
|
||||||
@@ -545,7 +427,7 @@ class Parser:
|
|||||||
|
|
||||||
result.register_advancement()
|
result.register_advancement()
|
||||||
self.advance()
|
self.advance()
|
||||||
return result.success(CallNode(atom, arg_nodes))
|
return result.success(nodes.CallNode(atom, arg_nodes))
|
||||||
return result.success(atom)
|
return result.success(atom)
|
||||||
|
|
||||||
def atom(self):
|
def atom(self):
|
||||||
@@ -555,15 +437,15 @@ class Parser:
|
|||||||
if token.type in (TT_INT, TT_FLOAT):
|
if token.type in (TT_INT, TT_FLOAT):
|
||||||
result.register_advancement()
|
result.register_advancement()
|
||||||
self.advance()
|
self.advance()
|
||||||
return result.success(NumberNode(token))
|
return result.success(nodes.NumberNode(token))
|
||||||
elif token.type == TT_STRING:
|
elif token.type == TT_STRING:
|
||||||
result.register_advancement()
|
result.register_advancement()
|
||||||
self.advance()
|
self.advance()
|
||||||
return result.success(StringNode(token))
|
return result.success(nodes.StringNode(token))
|
||||||
elif token.type == TT_IDENTIFIER:
|
elif token.type == TT_IDENTIFIER:
|
||||||
result.register_advancement()
|
result.register_advancement()
|
||||||
self.advance()
|
self.advance()
|
||||||
return result.success(VarAccessNode(token))
|
return result.success(nodes.VarAccessNode(token))
|
||||||
elif token.type == TT_LPAREN:
|
elif token.type == TT_LPAREN:
|
||||||
result.register_advancement()
|
result.register_advancement()
|
||||||
self.advance()
|
self.advance()
|
||||||
@@ -619,7 +501,7 @@ class Parser:
|
|||||||
factor = result.register(self.factor())
|
factor = result.register(self.factor())
|
||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
return result.success(UnaryOperationNode(token, factor))
|
return result.success(nodes.UnaryOperationNode(token, factor))
|
||||||
|
|
||||||
return self.power()
|
return self.power()
|
||||||
|
|
||||||
@@ -640,7 +522,7 @@ class Parser:
|
|||||||
node = result.register(self.com_expr())
|
node = result.register(self.com_expr())
|
||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
return result.success(UnaryOperationNode(operation, node))
|
return result.success(nodes.UnaryOperationNode(operation, node))
|
||||||
|
|
||||||
node = result.register(self.binary_operation(self.ar_expr, (TT_EE, TT_NE, TT_LT, TT_GT, TT_LTE, TT_GTE)))
|
node = result.register(self.binary_operation(self.ar_expr, (TT_EE, TT_NE, TT_LT, TT_GT, TT_LTE, TT_GTE)))
|
||||||
if result.error:
|
if result.error:
|
||||||
@@ -682,7 +564,7 @@ class Parser:
|
|||||||
expr = result.register(self.expr())
|
expr = result.register(self.expr())
|
||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
return result.success(VarAssignNode(var_name, expr))
|
return result.success(nodes.VarAssignNode(var_name, expr))
|
||||||
|
|
||||||
node = result.register(self.binary_operation(self.com_expr, ((TT_KEYWORD, "and"), (TT_KEYWORD, "or"))))
|
node = result.register(self.binary_operation(self.com_expr, ((TT_KEYWORD, "and"), (TT_KEYWORD, "or"))))
|
||||||
if result.error:
|
if result.error:
|
||||||
@@ -757,7 +639,7 @@ class Parser:
|
|||||||
else_case = result.register(self.expr())
|
else_case = result.register(self.expr())
|
||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
return result.success(IfNode(cases, else_case))
|
return result.success(nodes.IfNode(cases, else_case))
|
||||||
|
|
||||||
def for_expr(self):
|
def for_expr(self):
|
||||||
result = ParsedResult()
|
result = ParsedResult()
|
||||||
@@ -834,7 +716,7 @@ class Parser:
|
|||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
return result.success(ForNode(var_name, start_value, end_value, step_value, body))
|
return result.success(nodes.ForNode(var_name, start_value, end_value, step_value, body))
|
||||||
|
|
||||||
def while_expr(self):
|
def while_expr(self):
|
||||||
result = ParsedResult()
|
result = ParsedResult()
|
||||||
@@ -867,7 +749,7 @@ class Parser:
|
|||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
return result.success(WhileNode(condition, body))
|
return result.success(nodes.WhileNode(condition, body))
|
||||||
|
|
||||||
def fun_def(self):
|
def fun_def(self):
|
||||||
result = ParsedResult()
|
result = ParsedResult()
|
||||||
@@ -958,7 +840,7 @@ class Parser:
|
|||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
return result.success(FunDefNode(
|
return result.success(nodes.FunDefNode(
|
||||||
var_name_token,
|
var_name_token,
|
||||||
arg_name_tokens,
|
arg_name_tokens,
|
||||||
node_to_return
|
node_to_return
|
||||||
@@ -980,7 +862,7 @@ class Parser:
|
|||||||
right = result.register(rfunc())
|
right = result.register(rfunc())
|
||||||
if result.error:
|
if result.error:
|
||||||
return result
|
return result
|
||||||
left = BinaryOperationNode(left, operation, right)
|
left = nodes.BinaryOperationNode(left, operation, right)
|
||||||
|
|
||||||
return result.success(left)
|
return result.success(left)
|
||||||
|
|
||||||
@@ -1311,7 +1193,7 @@ class Interpreter:
|
|||||||
Number(node.token.value).set_context(context).set_pos(node.pos_start, node.pos_end)
|
Number(node.token.value).set_context(context).set_pos(node.pos_start, node.pos_end)
|
||||||
)
|
)
|
||||||
|
|
||||||
def visit_StringNode(self, node: StringNode, context: Context):
|
def visit_StringNode(self, node: nodes.StringNode, context: Context):
|
||||||
return RuntimeResult().success(
|
return RuntimeResult().success(
|
||||||
String(node.token.value).set_context(context).set_pos(node.pos_start, node.pos_end)
|
String(node.token.value).set_context(context).set_pos(node.pos_start, node.pos_end)
|
||||||
)
|
)
|
||||||
@@ -1383,7 +1265,7 @@ class Interpreter:
|
|||||||
return rt_result.failure(error)
|
return rt_result.failure(error)
|
||||||
return rt_result.success(result.set_pos(node.pos_start, node.pos_end))
|
return rt_result.success(result.set_pos(node.pos_start, node.pos_end))
|
||||||
|
|
||||||
def visit_UnaryOperationNode(self, node: UnaryOperationNode, context):
|
def visit_UnaryOperationNode(self, node: nodes.UnaryOperationNode, context):
|
||||||
result = RuntimeResult()
|
result = RuntimeResult()
|
||||||
number = result.register(self.visit(node.node, context))
|
number = result.register(self.visit(node.node, context))
|
||||||
if result.error:
|
if result.error:
|
||||||
@@ -1393,12 +1275,18 @@ class Interpreter:
|
|||||||
number, error = number.multiplied_by(Number(-1))
|
number, error = number.multiplied_by(Number(-1))
|
||||||
elif node.operation.matches(TT_KEYWORD, 'not'):
|
elif node.operation.matches(TT_KEYWORD, 'not'):
|
||||||
number, error = number.not_op()
|
number, error = number.not_op()
|
||||||
|
else:
|
||||||
|
return result.failure(exceptions.InvalidSyntaxErr(
|
||||||
|
node.pos_start,
|
||||||
|
node.pos_end,
|
||||||
|
"This unary operation is not valid in this context."
|
||||||
|
))
|
||||||
|
|
||||||
if error:
|
if error:
|
||||||
return result.failure(error)
|
return result.failure(error)
|
||||||
return result.success(number.set_pos(node.pos_start, node.pos_end))
|
return result.success(number.set_pos(node.pos_start, node.pos_end))
|
||||||
|
|
||||||
def visit_IfNode(self, node: IfNode, context):
|
def visit_IfNode(self, node: nodes.IfNode, context):
|
||||||
result = RuntimeResult()
|
result = RuntimeResult()
|
||||||
|
|
||||||
for condition, expr, in node.cases:
|
for condition, expr, in node.cases:
|
||||||
@@ -1422,7 +1310,7 @@ class Interpreter:
|
|||||||
|
|
||||||
return result.success(None)
|
return result.success(None)
|
||||||
|
|
||||||
def visit_ForNode(self, node: ForNode, context: Context):
|
def visit_ForNode(self, node: nodes.ForNode, context: Context):
|
||||||
result = RuntimeResult()
|
result = RuntimeResult()
|
||||||
|
|
||||||
start_value = result.register(self.visit(node.start_value_node, context))
|
start_value = result.register(self.visit(node.start_value_node, context))
|
||||||
@@ -1456,7 +1344,7 @@ class Interpreter:
|
|||||||
|
|
||||||
return result.success(None)
|
return result.success(None)
|
||||||
|
|
||||||
def visit_WhileNode(self, node: WhileNode, context: Context):
|
def visit_WhileNode(self, node: nodes.WhileNode, context: Context):
|
||||||
result = RuntimeResult()
|
result = RuntimeResult()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@@ -1473,7 +1361,7 @@ class Interpreter:
|
|||||||
|
|
||||||
return result.success(None)
|
return result.success(None)
|
||||||
|
|
||||||
def visit_FunDefNode(self, node: FunDefNode, context: Context):
|
def visit_FunDefNode(self, node: nodes.FunDefNode, context: Context):
|
||||||
result = RuntimeResult()
|
result = RuntimeResult()
|
||||||
|
|
||||||
fun_name = node.var_name_token.value if node.var_name_token else None
|
fun_name = node.var_name_token.value if node.var_name_token else None
|
||||||
@@ -1486,7 +1374,7 @@ class Interpreter:
|
|||||||
|
|
||||||
return result.success(fun_value)
|
return result.success(fun_value)
|
||||||
|
|
||||||
def visit_CallNode(self, node: CallNode, context: Context):
|
def visit_CallNode(self, node: nodes.CallNode, context: Context):
|
||||||
result = RuntimeResult()
|
result = RuntimeResult()
|
||||||
args = []
|
args = []
|
||||||
|
|
||||||
|
|||||||
120
internal/nodes.py
Normal file
120
internal/nodes.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
# d888888
|
||||||
|
# d88P aaa 888 888 888d88 .d88b. 888d88 8888b.
|
||||||
|
# d88P aaa 888 888 888P d88^^88b 888P 88b
|
||||||
|
# d88P aaa 888 888 888 888 888 888 .d888888
|
||||||
|
# d8888888888 Y88b 888 888 Y88..88P 888 888 888
|
||||||
|
# d88P aaa Y88888 888 Y88P 888 Y888888
|
||||||
|
# -- Copyright © 2023 Zandercraft. All rights reserved. --
|
||||||
|
"""
|
||||||
|
Purpose: Contains all node types for the AST of the language.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class NumberNode:
|
||||||
|
def __init__(self, token):
|
||||||
|
self.token = token
|
||||||
|
self.pos_start = self.token.pos_start
|
||||||
|
self.pos_end = self.token.pos_end
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.token}"
|
||||||
|
|
||||||
|
|
||||||
|
class StringNode:
|
||||||
|
def __init__(self, token):
|
||||||
|
self.token = token
|
||||||
|
self.pos_start = self.token.pos_start
|
||||||
|
self.pos_end = self.token.pos_end
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'{self.token}'
|
||||||
|
|
||||||
|
|
||||||
|
class VarAccessNode:
|
||||||
|
def __init__(self, var_name_token):
|
||||||
|
self.var_name_token = var_name_token
|
||||||
|
self.pos_start = self.var_name_token.pos_start
|
||||||
|
self.pos_end = self.var_name_token.pos_end
|
||||||
|
|
||||||
|
|
||||||
|
class VarAssignNode:
|
||||||
|
def __init__(self, var_name_token, value_node):
|
||||||
|
self.var_name_token = var_name_token
|
||||||
|
self.value_node = value_node
|
||||||
|
self.pos_start = self.var_name_token.pos_start
|
||||||
|
self.pos_end = self.var_name_token.pos_end
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryOperationNode:
|
||||||
|
def __init__(self, left_node, operation, right_node):
|
||||||
|
self.left_node = left_node
|
||||||
|
self.operation = operation
|
||||||
|
self.right_node = right_node
|
||||||
|
self.pos_start = self.left_node.pos_start
|
||||||
|
self.pos_end = self.right_node.pos_end
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"({self.left_node}, {self.operation}, {self.right_node})"
|
||||||
|
|
||||||
|
|
||||||
|
class UnaryOperationNode:
|
||||||
|
def __init__(self, operation, node):
|
||||||
|
self.operation = operation
|
||||||
|
self.node = node
|
||||||
|
self.pos_start = self.operation.pos_start
|
||||||
|
self.pos_end = self.node.pos_end
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'({self.operation}, {self.node})'
|
||||||
|
|
||||||
|
|
||||||
|
class IfNode:
|
||||||
|
def __init__(self, cases, else_case):
|
||||||
|
self.cases = cases
|
||||||
|
self.else_case = else_case
|
||||||
|
self.pos_start = self.cases[0][0].pos_start
|
||||||
|
self.pos_end = (self.else_case or self.cases[len(self.cases) - 1][0]).pos_end
|
||||||
|
|
||||||
|
|
||||||
|
class ForNode:
|
||||||
|
def __init__(self, var_name_token, start_value_node, end_value_node, step_value_node, body_node):
|
||||||
|
self.var_name_token = var_name_token
|
||||||
|
self.start_value_node = start_value_node
|
||||||
|
self.end_value_node = end_value_node
|
||||||
|
self.step_value_node = step_value_node
|
||||||
|
self.body_node = body_node
|
||||||
|
self.pos_start = self.var_name_token.pos_start
|
||||||
|
self.pos_end = self.body_node.pos_end
|
||||||
|
|
||||||
|
|
||||||
|
class WhileNode:
|
||||||
|
def __init__(self, condition_node, body_node):
|
||||||
|
self.condition_node = condition_node
|
||||||
|
self.body_node = body_node
|
||||||
|
self.pos_start = condition_node.pos_start
|
||||||
|
self.pos_end = body_node.pos_end
|
||||||
|
|
||||||
|
|
||||||
|
class FunDefNode:
|
||||||
|
def __init__(self, var_name_token, arg_name_tokens, body_node):
|
||||||
|
self.var_name_token = var_name_token
|
||||||
|
self.arg_name_tokens = arg_name_tokens
|
||||||
|
self.body_node = body_node
|
||||||
|
if self.var_name_token:
|
||||||
|
self.pos_start = self.var_name_token.pos_start
|
||||||
|
elif len(self.arg_name_tokens) > 0:
|
||||||
|
self.pos_start = self.arg_name_tokens[0].pos_start
|
||||||
|
else:
|
||||||
|
self.pos_start = self.body_node.pos_start
|
||||||
|
self.pos_end = self.body_node.pos_end
|
||||||
|
|
||||||
|
|
||||||
|
class CallNode:
|
||||||
|
def __init__(self, node_to_call, arg_nodes):
|
||||||
|
self.node_to_call = node_to_call
|
||||||
|
self.arg_nodes = arg_nodes
|
||||||
|
self.pos_start = self.node_to_call.pos_start
|
||||||
|
if len(self.arg_nodes) > 0:
|
||||||
|
self.pos_end = self.arg_nodes[len(self.arg_nodes) - 1].pos_end
|
||||||
|
else:
|
||||||
|
self.pos_end = self.node_to_call.pos_end
|
||||||
Reference in New Issue
Block a user