Mercurial > lcfOS
diff python/ks/irgenerator.py @ 146:91af0e40f868
Moved several files
author | Windel Bouwman |
---|---|
date | Fri, 22 Feb 2013 10:31:58 +0100 |
parents | python/ppci/frontends/ks/irgenerator.py@9e552d34bd60 |
children | 4fd075e8259c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ks/irgenerator.py Fri Feb 22 10:31:58 2013 +0100 @@ -0,0 +1,144 @@ +""" + Generates ir code from ast tree. +""" + +from .nodes import * +from ...core.errors import Error +from ... import core +from .builtin import real, integer, boolean, char, void + +def coreType(typ): + """ Return the correct core type given a type """ + if type(typ) is BaseType: + if typ is integer: + return core.i32 + if typ is void: + return core.void + elif type(typ) is ProcedureType: + rType = coreType(typ.returntype) + fpTypes = [coreType(p.typ) for p in typ.parameters] + return core.FunctionType(rType, fpTypes) + print(typ) + raise NotImplementedError() + +class KsIrGenerator: + def __init__(self): + self.builder = core.IRBuilder() + # Code generation functions: + def genexprcode(self, node): + """ Generate code for expressions! """ + if isinstance(node, Binop): + """ Handle a binary operation (two arguments) of some kind """ + lhs = self.genexprcode(node.a) + rhs = self.genexprcode(node.b) + + if node.op == '*': + if node.typ.isType(integer): + return self.builder.createMul(lhs, rhs) + elif node.op == '+': + if node.typ.isType(integer): + return self.builder.createAdd(lhs, rhs) + elif node.op == '-': + if node.typ.isType(integer): + return self.builder.createSub(lhs, rhs) + Error('Unknown binop or type {0}'.format(node)) + + elif isinstance(node, Designator): + # dereference, array index. Make sure that the result comes into a register + if len(node.selectors) > 0: + Error('Only integer types implemented') + else: + # No selectors, load variable directly + print(node) + #Error('Cannot load variable type {0}'.format(node.typ)) + elif type(node) is Constant: + return core.Constant(node.value, coreType(node.typ)) + else: + Error('Cannot generate expression code for: {0}'.format(node)) + + def gencode(self, node): + """ Code generation function for AST nodes """ + if isinstance(node, Module): + # Create module: + self.mod = core.Module(node.name) + + globs = node.symtable.getAllLocal(Variable) + for g in globs: + print('global:', g) + # Loop over all functions: + print(node.symtable) + node.symtable.printTable() + funcs = node.symtable.getAllLocal(Procedure) + for f in funcs: + self.gencode(f) + # Create a function called init for this module: + self.mod.dump() + return self.mod + + elif type(node) is Procedure: + ftype = coreType(node.typ) + print('function', node, ftype) + func = core.Function(ftype, node.name, self.mod) + bb = core.BasicBlock() + func.basicblocks.append(bb) + self.builder.setInsertPoint(bb) + self.gencode(node.block) + self.builder.setInsertPoint(None) + variables = node.symtable.getAllLocal(Variable) + print(variables) + + elif isinstance(node, StatementSequence): + for s in node.statements: + self.gencode(s) + + elif type(node) is ProcedureCall: + # Prepare parameters on the stack: + print("TODO") + + elif type(node) is Assignment: + if node.lval.typ.isType(integer): + print('assign') + rhs = self.genexprcode(node.rval) # Calculate the value that has to be stored. + #self.gencode(node.lval) + print("TODO: assigment") + + else: + Error('Assignments of other types not implemented') + + elif type(node) is IfStatement: + self.genexprcode(node.condition) + print("TODO IF") + if node.falsestatement: + # If with else clause + pass + else: + # If without else clause + pass + + elif isinstance(node, WhileStatement): + self.genexprcode(node.condition) + self.gencode(node.dostatements) + elif type(node) is ForStatement: + # Initial load of iterator variable: + self.genexprcode(node.begin) + self.genexprcode(node.end) + self.gencode(node.statements) + Error('No implementation of FOR statement') + + elif isinstance(node, EmptyStatement): + pass # That was easy :) + + elif type(node) is StringConstant: + self.strings.append(node) + + elif type(node) is Designator: + Error('Can only gencode for designator with selectors') + else: + print('not generating code for {0}'.format(node)) + + def generateIr(self, context, ast): + """ ir generation front end """ + # Create a new context for this code. + self.context = context + return self.gencode(ast) +