1. from string import ascii_uppercase
  2. from pyparsing import *
  3.  
  4.  
  5. class Node(object):
  6.     def __init__(self, s, loc, toks):
  7.         self.children = toks
  8.  
  9.     def __repr__(self):
  10.         return '%s(%s)' % (self.__class__.__name__, ', '.join(map(str, self.children)))
  11.  
  12.     @classmethod
  13.     def grammar(cls, expression):
  14.         return expression.setParseAction(cls)
  15.  
  16.  
  17. class Module(Node):
  18.     def __init__(self, s, loc, toks):
  19.         self.body = toks
  20.         super().__init__(s, loc, toks)
  21. class Expression(Node):
  22.     def __init__(self, s, loc, toks):
  23.         self.left, self.op, self.right = toks[0]
  24.         super().__init__(s, loc, toks)
  25. class Main(Node):
  26.     def __init__(self, s, loc, toks):
  27.         self.body = toks
  28.         super().__init__(s, loc, toks)
  29. class AliasDefinition(Node):
  30.     def __init__(self, s, loc, toks):
  31.         self.alias, self.value = toks
  32.         super().__init__(s, loc, toks)
  33. class Alias(Node):
  34.     def __init__(self, s, loc, toks):
  35.         self.alias = toks[0]
  36.         super().__init__(s, loc, toks)
  37. class Assignment(Node):
  38.     def __init__(self, s, loc, toks):
  39.         self.left, self.right = toks
  40.         super().__init__(s, loc, toks)
  41. class MemoryAssignment(Node):
  42.     def __init__(self, s, loc, toks):
  43.         self.left, self.right = toks
  44.         super().__init__(s, loc, toks)
  45. class AugmentedAssignment(Node):
  46.     def __init__(self, s, loc, toks):
  47.         self.left, self.operator, self.right = toks
  48.         super().__init__(s, loc, toks)
  49. class BuiltinCall(Node):
  50.     def __init__(self, s, loc, toks):
  51.         self.name = toks[0]
  52.         self.args = toks[1:]
  53.         super().__init__(s, loc, toks)
  54. class FunctionCall(Node):
  55.     def __init__(self, s, loc, toks):
  56.         self.name = toks[0]
  57.         super().__init__(s, loc, toks)
  58. class Register(Node):
  59.     def __init__(self, s, loc, toks):
  60.         self.r = toks[0]
  61.         super().__init__(s, loc, toks)
  62. class Name(Node):
  63.     def __init__(self, s, loc, toks):
  64.         self.n = toks[0]
  65.         super().__init__(s, loc, toks)
  66. class Variable(Node):
  67.     def __init__(self, s, loc, toks):
  68.         self.v = toks[0]
  69.         super().__init__(s, loc, toks)
  70. class String(Node):
  71.     def __init__(self, s, loc, toks):
  72.         self.s = toks[0][1:-1]
  73.         super().__init__(s, loc, toks)
  74. class Hex(Node):
  75.     def __init__(self, s, loc, toks):
  76.         self.h = toks[0]
  77.         super().__init__(s, loc, toks)
  78.     @property
  79.     def i(self):
  80.         return int(self.h, 16)
  81. class Integer(Node):
  82.     def __int__(self, s, loc, toks):
  83.         super().__init__(s, loc, toks)
  84.     @property
  85.     def i(self):
  86.         return int(self.children[0])
  87. class MemoryLocation(Node):
  88.     def __init__(self, s, loc, toks):
  89.         if len(toks) == 1:
  90.             self.location = toks[0]
  91.             self.simple = True
  92.         else:
  93.             self.left, self.op, self.right = toks
  94.             self.simple = False
  95.         super().__init__(s, loc, toks)
  96. class ForLoop(Node):
  97.     def __init__(self, s, loc, toks):
  98.         self.targets, self.iterator, self.body = toks
  99.         super().__init__(s, loc, toks)
  100. class FunctionDefinition(Node):
  101.     def __init__(self, s, loc, toks):
  102.         self.alias = toks[0]
  103.         self.body = toks[1:]
  104.         super().__init__(s, loc, toks)
  105. class Import(Node):
  106.     def __init__(self, s, loc, toks):
  107.         self.module = '.'.join(toks[0])
  108.         super().__init__(s, loc, toks)
  109. class Data(Node):
  110.     def __init__(self, s, loc, toks):
  111.         self.alias = toks[0]
  112.         self.values = toks[1:]
  113.         super().__init__(s, loc, toks)
  114.  
  115.  
  116. indentStack = [1]
  117.  
  118. def checkPeerIndent(s,l,t):
  119.     curCol = col(l,s)
  120.     if curCol != indentStack[-1]:
  121.         if (not indentStack) or curCol > indentStack[-1]:
  122.             raise ParseFatalException(s,l,"illegal nesting")
  123.         raise ParseException(s,l,"not a peer entry")
  124.  
  125. def checkSubIndent(s,l,t):
  126.     curCol = col(l,s)
  127.     if curCol > indentStack[-1]:
  128.         indentStack.append( curCol )
  129.     else:
  130.         raise ParseException(s,l,"not a subentry")
  131.  
  132. def checkUnindent(s,l,t):
  133.     if l >= len(s): return
  134.     curCol = col(l,s)
  135.     if not(curCol < indentStack[-1] and curCol <= indentStack[-2]):
  136.         raise ParseException(s,l,"not an unindent")
  137.  
  138. def doUnindent():
  139.     indentStack.pop()
  140.  
  141. INDENT = lineEnd.suppress() + empty + empty.copy().setParseAction(checkSubIndent)
  142. UNDENT = FollowedBy(empty).setParseAction(checkUnindent)
  143. UNDENT.setParseAction(doUnindent)
  144.  
  145. stmt = Forward()
  146. suite = OneOrMore(empty + stmt.setParseAction(checkPeerIndent))
  147.  
  148. register = Register.grammar(Word(ascii_uppercase, exact=1))
  149. _nameish = Word(alphas + '_', alphanums + '_')
  150. name = Name.grammar(delimitedList(_nameish, '.', True))
  151. func_decl = Suppress("def") + _nameish + Suppress(":")
  152. func_def = FunctionDefinition.grammar(func_decl + INDENT + suite + UNDENT)
  153. alias_identifier = Alias.grammar(_nameish)
  154.  
  155. maindef = Main.grammar(Suppress('main:') + INDENT + suite + UNDENT)
  156.  
  157. string = String.grammar(dblQuotedString) | String.grammar(sglQuotedString)
  158.  
  159. numeric = Hex.grammar(Combine('0x' + Word(hexnums, exact=4))) | Integer.grammar(Word(nums))
  160.  
  161. constant = string | numeric
  162.  
  163. memloc = MemoryLocation.grammar(Suppress('[') + (register | numeric) + Optional('+' + (register | numeric)) + Suppress(']'))
  164.  
  165. func_call = FunctionCall.grammar(name + Suppress("()"))
  166. builtin_names = Forward()
  167. for key in BUILTINS:
  168.     builtin_names |= Word(key)
  169. builtin_call = BuiltinCall.grammar(builtin_names + Suppress("(") + Optional(delimitedList(constant)) + Suppress(")"))
  170.  
  171. operand = builtin_call | func_call | constant
  172.  
  173. expr = Expression.grammar(operatorPrecedence(operand, [
  174.     (Literal('<<'), 2, opAssoc.LEFT),
  175.     (Literal('|'), 2, opAssoc.LEFT),
  176. ]))
  177.  
  178. for_decl = Suppress('for') + Group(delimitedList(register)) + Suppress('in') + (string | alias_identifier) + Suppress(':')
  179. for_loop = ForLoop.grammar(for_decl + INDENT + Group(suite) + UNDENT)
  180.  
  181. math_operator = Literal('+') | Literal('-') | Literal('*') | Literal('/') | Literal('|') | Literal('&') | Literal('<<') | Literal('>>')
  182.  
  183. rvalue = (alias_identifier | memloc | numeric | expr)
  184. assignment = Assignment.grammar(register + Suppress("=") + rvalue)
  185. aug_assignment = AugmentedAssignment.grammar(register + math_operator + Suppress('=') + rvalue)
  186. mem_assignment = MemoryAssignment.grammar(memloc + Suppress('=') + (register | numeric))
  187. stmt << (assignment | aug_assignment | mem_assignment | for_loop | func_call)
  188.  
  189. alias_rvalue = (builtin_call | name | numeric | expr)
  190.  
  191. aliasdef = AliasDefinition.grammar(alias_identifier + Suppress("=") + alias_rvalue)
  192.  
  193. import_def = Import.grammar(Suppress('import') + Group(delimitedList(Word(alphas, alphanums), '.')))
  194.  
  195. data_rvalue = delimitedList(alias_rvalue | string, ',')
  196.  
  197. datadef = Data.grammar(alias_identifier + Suppress("= data") + data_rvalue)
  198.  
  199. grammar = Module.grammar(ZeroOrMore(import_def) + ZeroOrMore(datadef | aliasdef) + Optional(maindef) + ZeroOrMore(func_def))