view 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 source

"""
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'