fx92-interpreter/ast.py

75 lines
1.7 KiB
Python

# fx-92 Scientifique Collège+ language interpreter: AST definition
import enum
#---
# Internal AST node representation
#---
@enum.unique
class N(enum.IntEnum):
# Core nodes
PROGRAM = enum.auto()
# Basic statements
FORWARD = enum.auto()
ROTATE = enum.auto()
ORIENT = enum.auto()
GOTO = enum.auto()
PENDOWN = enum.auto()
PENUP = enum.auto()
ASSIGN = enum.auto()
INPUT = enum.auto()
MESSAGE = enum.auto()
PRINT = enum.auto()
STYLE = enum.auto()
WAIT = enum.auto()
# Flow control
REPEAT = enum.auto()
WHILE = enum.auto()
IFELSE = enum.auto()
# Expressions
ADD = enum.auto()
SUB = enum.auto()
MUL = enum.auto()
DIV = enum.auto()
MINUS = enum.auto()
EXP = enum.auto()
VAR = enum.auto()
CONST = enum.auto()
#---
# AST nodes
#---
class Node:
def __init__(self, type, *args):
"""Instantiate a new AST node."""
self.type = type
self.args = args
def __str__(self):
try:
name = N(self.type).name
return f"<Node:{name}>"
except ValueError:
return f"<Node:{hex(self.type)}>"
def simplify(self):
simpl = lambda n: n.simplify() if isinstance(n, Node) else n
self.args = [ simpl(arg) for arg in self.args ]
arity = len(self.args)
if self.type == N.MUL and arity == 0:
return Node(N.CONST, 1)
if self.type == N.MUL and arity == 1:
return self.args[0]
if self.type == N.ADD and arity == 0:
return Node(N.CONST, 0)
if self.type == N.ADD and arity == 1:
return self.args[0]
return self