diff ide/compiler/nodes.py @ 1:92df07bc2081

Initial import of compiler
author windel
date Sun, 18 Sep 2011 19:00:29 +0200
parents
children 0d5ef85b8698
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ide/compiler/nodes.py	Sun Sep 18 19:00:29 2011 +0200
@@ -0,0 +1,303 @@
+"""
+Parse tree elements
+"""
+class Node:
+   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 Symbol(Node):
+  pass
+
+# Selectors:
+class Field(Node):
+   def __init__(self, fieldname):
+      self.fieldname = fieldname
+   def __repr__(self):
+      return 'FLD {0}'.format(self.fieldname)
+
+class Index(Node):
+   def __init__(self, index, typ):
+      self.index = index
+      self.typ = typ
+   def __repr__(self):
+      return 'IDX {0}'.format(self.index)
+
+class Deref(Node):
+   pass
+
+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 ArrayType:
+         return (a.dimension == b.dimension) and isType(a.elementType, b.elementType)
+      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, size):
+    self.name = name
+    self.size = size
+  def __repr__(self):
+    return '[TYPE {0}]'.format(self.name)
+
+class NilType(Node):
+   # TODO: how to handle nil values??
+   def __repr__(self):
+      return 'NILTYPE'
+
+class ArrayType(Type):
+  def __init__(self, dimension, elementType):
+    self.dimension = dimension
+    self.elementType = elementType
+    self.size = elementType.size * dimension
+  def __repr__(self):
+    return '[ARRAY {0} of {1}]'.format(self.dimension, self.elementType)
+
+class RecordType(Type):
+   def __init__(self, fields):
+      self.fields = fields
+      self.size = 0
+      for fieldname in self.fields:
+         self.size += self.fields[fieldname].size
+   def __repr__(self):
+      return '[RECORD {0}]'.format(self.fields)
+
+class PointerType(Type):
+   def __init__(self, pointedType):
+      self.pointedType = pointedType
+      self.size = 8
+   def __repr__(self):
+      return '[POINTER {0}]'.format(self.pointedType)
+
+class ProcedureType(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)
+
+# Classes for constants like numbers and strings:
+class StringConstant(Symbol):
+  def __init__(self, txt):
+    self.txt = txt
+    self.typ = 'string'
+  def __repr__(self):
+    return "STRING '{0}'".format(self.txt)
+
+# Variables, parameters, local variables, constants:
+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, kind, name, typ):
+      self.kind = kind
+      self.name = name
+      self.typ = typ
+   def __repr__(self):
+      return 'PARAM {0} {1} {2}'.format(self.kind, self.name, self.typ)
+
+# Operations:
+class Unop(Node):
+   def __init__(self, a, op, typ):
+      self.a = a
+      self.op = op # Operation: '+', '-', '*', '/', 'mod'
+      self.typ = typ
+      self.place = None
+   def __repr__(self):
+      return 'UNOP {0}'.format(self.op)
+
+class Binop(Node):
+   def __init__(self, a, op, b, typ):
+      self.a = a
+      self.b = b
+      self.op = op # Operation: '+', '-', '*', '/', 'mod'
+      self.typ = typ # Resulting type :)
+      self.place = None
+   def __repr__(self):
+      return 'BINOP {0} {1}'.format(self.op, self.typ)
+
+class Relop(Node):
+   def __init__(self, a, relop, b, typ):
+      self.a = a
+      self.relop = relop
+      self.b = b
+      self.typ = typ
+   def __repr__(self):
+      return 'RELOP {0}'.format(self.relop)
+
+# Modules
+class Module(Node):
+   def __init__(self, name):
+      self.name = name
+   def __repr__(self):
+      return 'MODULE {0}'.format(self.name)
+
+# Imports and Exports:
+class ImportedSymbol(Node):
+   def __init__(self, modname, name):
+      self.modname = modname
+      self.name  = name
+   def __repr__(self):
+      return 'IMPORTED SYMBOL {0}'.format(self.name)
+
+class ExportedSymbol(Node):
+   def __init__(self, name, typ):
+      self.name  = name
+      self.typ = typ
+   def __repr__(self):
+      return 'EXPORTED PROCEDURE {0} : {1}'.format(self.name, self.typ)
+
+# Procedure types
+class BuiltinProcedure(Node):
+   def __init__(self, name, typ):
+      self.name  = name
+      self.typ = typ
+   def __repr__(self):
+      return 'BUILTIN PROCEDURE {0} : {1}'.format(self.name, self.typ)
+
+class Procedure(Symbol):
+   """ Actual implementation of a function """
+   def __init__(self, name, typ, block, symtable, retexpr):
+      self.name = name
+      self.block = block
+      self.symtable = symtable
+      self.typ = typ
+      self.retexpr = retexpr
+   def __repr__(self):
+      return 'PROCEDURE {0} {1}'.format(self.name, self.typ)
+
+# Statements
+class StatementSequence(Node):
+   def __init__(self, statements):
+      self.statements = statements
+   def __repr__(self):
+      return 'STATEMENTSEQUENCE'
+
+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
+    self.typ = proc.typ.returntype
+  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 CaseStatement(Node):
+   def __init__(self, condition):
+      self.condition = condition
+   def __repr__(self):
+     return 'CASE-statement'
+
+class WhileStatement(Node):
+   def __init__(self, condition, statements):
+      self.condition = condition
+      self.dostatements = statements
+   def __repr__(self):
+      return 'WHILE-statement'
+
+class ForStatement(Node):
+   def __init__(self, variable, begin, end, increment, statements):
+      self.variable = variable
+      self.begin = begin
+      self.end = end
+      self.increment = increment
+      self.statements = statements
+   def __repr__(self):
+      return 'FOR-statement'
+
+class AsmCode(Node):
+   def __init__(self, asmcode):
+      self.asmcode = asmcode
+   def __repr__(self):
+      return 'ASM CODE'
+