Mercurial > lcfOS
view python/c3/astnodes.py @ 149:74241ca312cc
Fixes on parser and semantics
author | Windel Bouwman |
---|---|
date | Fri, 01 Mar 2013 11:43:52 +0100 |
parents | e5263f74b287 |
children | 4ae0e02599de |
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(Node): 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, name=None): self.name = name self.value = value def __repr__(self): return 'CONSTANT {0} = {1}'.format(self.name, self.value) class Variable(Symbol): def __init__(self, name, typ): self.name = name self.typ = typ self.isLocal = False self.isReadOnly = False self.isParameter = False def __repr__(self): return 'VAR {0} : {1}'.format(self.name, self.typ) 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}'.format(self.op) # 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=None, block=None): self.name = name self.body = 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 ReturnStatement(Node): def __init__(self, expr): self.expr = expr def __repr__(self): return 'RETURN 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'