diff python/c3/astnodes.py @ 148:e5263f74b287

Added c3 language frontend initial parser
author Windel Bouwman
date Fri, 01 Mar 2013 10:24:01 +0100
parents
children 74241ca312cc
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/c3/astnodes.py	Fri Mar 01 10:24:01 2013 +0100
@@ -0,0 +1,196 @@
+"""
+AST nodes for the c3 language.
+"""
+
+class Node:
+   location = None
+   def getChildren(self):
+      children = []
+      members = dir(self)
+      for member in members:
+         member = getattr(self, member)
+         if isinstance(member, Node):
+            children.append(member)
+         elif type(member) is list:
+            for mi in member:
+               if isinstance(mi, Node):
+                  children.append(mi)
+      return children
+
+
+class Id(Node):
+   def __init__(self, tok, pub):
+      self.name = tok.val
+      self.is_public = pub
+   def __repr__(self):
+      return 'ID {0}'.format(self.name)
+
+# Selectors:
+class Designator(Node):
+   def __init__(self, obj, selectors, typ):
+      self.obj = obj
+      self.selectors = selectors
+      self.typ = typ
+   def __repr__(self):
+      return 'DESIGNATOR {0}, selectors {1}, type {2}'.format(self.obj, self.selectors, self.typ)
+
+"""
+Type classes
+"""
+def isType(a, b):
+   """ Compare types a and b and check if they are equal """
+   if type(a) is type(b):
+      if type(a) is BaseType:
+         return (a.name == b.name) and (a.size == b.size)
+      elif type(a) is ProcedureType:
+         if len(a.parameters) != len(b.parameters):
+            print('Number of parameters does not match')
+            return False
+         for aparam, bparam in zip(a.parameters, b.parameters):
+            if not isType(aparam.typ, bparam.typ):
+               print('Parameter {0} does not match parameter {1}'.format(aparam, bparam))
+               return False
+         if a.result is None:
+            # TODO: how to handle a None return type??
+            pass
+         if not isType(a.result, b.result):
+            print('Procedure return value mismatch {0} != {1}'.format(a.result, b.result))
+            return False
+         return True
+      else:
+         print(a)
+         print(b)
+         Error('Not implemented {0}'.format(a))
+   else:
+      return False
+
+class Type:
+   def isType(self, b):
+      return isType(self, b)
+
+class BaseType(Type):
+  def __init__(self, name):
+    self.name = name
+  def __repr__(self):
+    return '[TYPE {0}]'.format(self.name)
+
+class FunctionType(Type):
+   def __init__(self, parameters, returntype):
+      self.parameters = parameters
+      self.returntype = returntype
+   def __repr__(self):
+      return '[PROCTYPE {0} RET {1}]'.format(self.parameters, self.returntype)
+
+class DefinedType(Type):
+   def __init__(self, name, typ):
+      self.name = name
+      self.typ = typ
+   def __repr__(self):
+      return 'Named type {0} of type {1}'.format(self.name, self.typ)
+
+# Variables, parameters, local variables, constants:
+class Symbol(Node):
+   pass
+
+class Constant(Symbol):
+   def __init__(self, value, typ, name=None, public=False):
+      self.name = name
+      self.value = value
+      self.typ = typ
+      self.public = public
+   def __repr__(self):
+      return 'CONSTANT {0} = {1}'.format(self.name, self.value)
+
+class Variable(Symbol):
+   def __init__(self, name, typ, public):
+      self.name = name
+      self.typ = typ
+      self.public = public
+      self.isLocal = False
+      self.isReadOnly = False
+      self.isParameter = False
+   def __repr__(self):
+      txt = '[public] ' if self.public else ''
+      return '{2}VAR {0} : {1}'.format(self.name, self.typ, txt)
+
+class Parameter(Node):
+   """ A parameter has a passing method, name and typ """
+   def __init__(self, name, typ):
+      self.name = name
+      self.typ = typ
+   def __repr__(self):
+      return 'PARAM {0} {1}'.format(self.name, self.typ)
+
+# Operations:
+class Unop(Node):
+   def __init__(self, a, op):
+      self.a = a
+      self.op = op 
+   def __repr__(self):
+      return 'UNOP {0}'.format(self.op)
+
+class Binop(Node):
+   def __init__(self, a, op, b):
+      self.a = a
+      self.b = b
+      self.op = op # Operation: '+', '-', '*', '/', 'mod'
+   def __repr__(self):
+      return 'BINOP {0} {1}'.format(self.op, self.typ)
+
+# Modules
+class Package(Node):
+   def __init__(self, name):
+      self.name = name
+   def __repr__(self):
+      return 'PACKAGE {0}'.format(self.name)
+
+# Procedure types
+class Procedure(Symbol):
+   """ Actual implementation of a function """
+   def __init__(self, name, typ, block):
+      self.name = name
+      self.block = block
+      self.typ = typ
+   def __repr__(self):
+      return 'PROCEDURE {0} {1}'.format(self.name, self.typ)
+
+# Statements
+class CompoundStatement(Node):
+   def __init__(self, statements):
+      self.statements = statements
+   def __repr__(self):
+      return 'COMPOUND STATEMENT'
+
+class EmptyStatement(Node):
+   def __repr__(self):
+      return 'EMPTY STATEMENT'
+
+class Assignment(Node):
+   def __init__(self, lval, rval):
+      self.lval = lval
+      self.rval = rval
+   def __repr__(self):
+      return 'ASSIGNMENT'
+
+class ProcedureCall(Node):
+  def __init__(self, proc, args):
+    self.proc = proc
+    self.args = args
+  def __repr__(self):
+    return 'CALL {0} '.format(self.proc)
+
+class IfStatement(Node):
+   def __init__(self, condition, truestatement, falsestatement=None):
+      self.condition = condition
+      self.truestatement = truestatement
+      self.falsestatement = falsestatement
+   def __repr__(self):
+      return 'IF-statement'
+
+class WhileStatement(Node):
+   def __init__(self, condition, statements):
+      self.condition = condition
+      self.dostatements = statements
+   def __repr__(self):
+      return 'WHILE-statement'
+