# HG changeset patch # User Windel Bouwman # Date 1362330875 -3600 # Node ID 8f3924b6076eb060b4b58ccd0e04875b850dca51 # Parent 1b4a85bdd99c68230e950cff4df7a75958ee19db Added some code generator things diff -r 1b4a85bdd99c -r 8f3924b6076e python/c3/codegenerator.py --- a/python/c3/codegenerator.py Sun Mar 03 15:50:34 2013 +0100 +++ b/python/c3/codegenerator.py Sun Mar 03 18:14:35 2013 +0100 @@ -18,13 +18,45 @@ m.Globals.append(v) def genFunction(m, fnc): - f = ir.Function() + ft = genType(fnc.typ) + f = ir.Function(fnc.name, ft) m.Globals.append(f) + bb = ir.BasicBlock() + f.BasicBlocks.append(bb) + genCode(bb, fnc.body) + +def genCode(bb, code): + if type(code) is astnodes.CompoundStatement: + for s in code.statements: + genCode(bb, s) + elif type(code) is astnodes.Assignment: + genCode(bb, code.rval) + print('assign') + elif type(code) is astnodes.IfStatement: + genCode(bb, code.condition) + genCode(bb, code.truestatement) + print('If!') + elif type(code) is astnodes.Binop: + genCode(bb, code.a) + genCode(bb, code.b) + a = 1 + b = 2 + if code.op == '+': + bb.Instructions.append(ir.AddInstruction(a, b)) + else: + bb.Instructions.append(ir.BinaryOperator(code.op, a, b)) + elif type(code) is astnodes.Constant: + print('CST') + bb.Instructions.append(ir.ImmLoadInstruction(code.value)) + else: + print('Unknown:', code) + +def genType(t): + return ir.Type() class CodeGenerator: """ Generates intermediate code """ def gencode(self, ast): - print('Code generator') assert type(ast) is astnodes.Package return genModule(ast) diff -r 1b4a85bdd99c -r 8f3924b6076e python/c3/parser.py --- a/python/c3/parser.py Sun Mar 03 15:50:34 2013 +0100 +++ b/python/c3/parser.py Sun Mar 03 18:14:35 2013 +0100 @@ -61,7 +61,6 @@ self.parseFunctionDefinition() elif self.Peak == 'var': self.parseVarDef() - self.Consume(';') else: self.Error('Expected function or variable') @@ -88,6 +87,7 @@ parseVar() while self.hasConsumed(','): parseVar() + self.Consume(';') # Procedures def parseFunctionDefinition(self): @@ -114,6 +114,7 @@ lval = astnodes.VariableUse(lval) self.Consume('=') rval = self.parseExpression() + self.Consume(';') return astnodes.Assignment(lval, rval) def parseProcedureCall(self, procedure): @@ -148,15 +149,14 @@ def parseReturnStatement(self): self.Consume('return') expr = self.parseExpression() + self.Consume(';') return astnodes.ReturnStatement(expr) def parseCompoundStatement(self): self.Consume('{') - statements = [self.parseStatement()] - while self.hasConsumed(';'): - if self.Peak == '}': break # Permit last ';' + statements = [] + while not self.hasConsumed('}'): statements.append(self.parseStatement()) - self.Consume('}') return astnodes.CompoundStatement(statements) def parseStatement(self): @@ -168,6 +168,7 @@ elif self.Peak == '{': return self.parseCompoundStatement() elif self.Peak == ';': + self.Consume(';') return astnodes.EmptyStatement() elif self.Peak == 'var': return self.parseVarDef() diff -r 1b4a85bdd99c -r 8f3924b6076e python/ir/__init__.py --- a/python/ir/__init__.py Sun Mar 03 15:50:34 2013 +0100 +++ b/python/ir/__init__.py Sun Mar 03 18:14:35 2013 +0100 @@ -1,4 +1,7 @@ from .module import Module, Function, BasicBlock from .value import Value -from .types import Type, i8, i16, i32, void +from .module import Type, FunctionType +from .module import i8, i16, i32, void +from .instruction import AddInstruction, BinaryOperator, ImmLoadInstruction + diff -r 1b4a85bdd99c -r 8f3924b6076e python/ir/instruction.py --- a/python/ir/instruction.py Sun Mar 03 15:50:34 2013 +0100 +++ b/python/ir/instruction.py Sun Mar 03 18:14:35 2013 +0100 @@ -18,13 +18,17 @@ def __init__(self, operation, value1, value2): assert value1 assert value2 - print('operation is in binops:', operation in BinOps) + #print('operation is in binops:', operation in BinOps) # Check types of the two operands: self.value1 = value1 self.value2 = value2 self.operation = operation -class LoadInstruction(Instruction): - def __init__(self, ptr, name, insertBefore): - self.setName(name) +class AddInstruction(BinaryOperator): + def __init__(self, a, b): + super().__init__('add', a, b) +class ImmLoadInstruction(Instruction): + def __init__(self, value): + self.value = value + diff -r 1b4a85bdd99c -r 8f3924b6076e python/ir/llvmtype.py --- a/python/ir/llvmtype.py Sun Mar 03 15:50:34 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ - -class Type: - def __init__(self): - pass - -class IntegerType(Type): - def __init__(self, bits): - super().__init__() - self.bits = bits - -class VoidType(Type): - pass - -class FunctionType(Type): - def __init__(self, resultType, parameterTypes): - super().__init__() - assert type(parameterTypes) is list - self.resultType = resultType - self.parameterTypes = parameterTypes - -# Default types: -i8 = IntegerType(8) -i16 = IntegerType(16) -i32 = IntegerType(32) -void = VoidType() - - diff -r 1b4a85bdd99c -r 8f3924b6076e python/ir/module.py --- a/python/ir/module.py Sun Mar 03 15:50:34 2013 +0100 +++ b/python/ir/module.py Sun Mar 03 18:14:35 2013 +0100 @@ -1,5 +1,33 @@ from .symboltable import SymbolTable +# Types: +class Type: + def __init__(self): + pass + +class IntegerType(Type): + def __init__(self, bits): + super().__init__() + self.bits = bits + +class VoidType(Type): + pass + +class FunctionType(Type): + def __init__(self, resultType, parameterTypes): + super().__init__() + assert type(parameterTypes) is list + self.resultType = resultType + self.parameterTypes = parameterTypes + +# Default types: +i8 = IntegerType(8) +i16 = IntegerType(16) +i32 = IntegerType(32) +void = VoidType() + +# IR-Structures: + class Module: """ Main container for a piece of code. Contains globals and functions. """ def __init__(self, name): @@ -23,10 +51,8 @@ self.name = name self.functiontype = functiontype - self.module.Functions.append(self) self.basicblocks = [] self.arguments = [] - # Construct formal arguments depending on function type BasicBlocks = property(lambda self: self.basicblocks) Arguments = property(lambda self: self.arguments) ReturnType = property(lambda self: self.functiontype.returnType) diff -r 1b4a85bdd99c -r 8f3924b6076e python/testc3.py --- a/python/testc3.py Sun Mar 03 15:50:34 2013 +0100 +++ b/python/testc3.py Sun Mar 03 18:14:35 2013 +0100 @@ -1,4 +1,4 @@ -import c3, time, ppci +import c3, time, ppci, x86 testsrc = """ package test; @@ -16,20 +16,24 @@ var int zero = i - 2; if (i > 1) { - buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1 + buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1; } else { ;;; - }; + } t2(2, 3); } function int t2(u32 a, u32 b) { + if (a > 0) + { + a = 2 + t2(a - 1); + } + return a + b; - a = 2;// + t2(2); } var int hahaa = 23 * 2; @@ -57,6 +61,7 @@ tc = c3.TypeChecker(diag) al = c3.Analyzer(diag) cg = c3.CodeGenerator() + x86gen = x86.X86CodeGen(diag) t1 = time.time() p.parseSource(src) t2 = time.time() @@ -77,8 +82,10 @@ if ok: print('Generating code') i = cg.gencode(sema.mod) + print(i) print(i.Globals) + x86gen.genBin(i) else: print('Not generating code') diff -r 1b4a85bdd99c -r 8f3924b6076e python/x86.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/x86.py Sun Mar 03 18:14:35 2013 +0100 @@ -0,0 +1,9 @@ +import ppci + +class X86CodeGen: + def __init__(self, diag): + self.diag = diag + + def genBin(self, i): + print(i) +