75 lines
1.7 KiB
Python
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
|