changeset 313:04cf4d26a3bc

Added constant function
author Windel Bouwman
date Wed, 18 Dec 2013 18:02:26 +0100
parents 2c9768114877
children 38f5f298ce0e
files kernel/make.py python/ppci/c3/codegenerator.py python/ppci/c3/parser.py python/ppci/c3/visitor.py python/ppci/codegen/interferencegraph.py python/zcc.py test/testc3.py test/testzcc.py user/hello.c3 user/ipc.c3 user/lib.c3 user/makeuser.py
diffstat 12 files changed, 81 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/kernel/make.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/kernel/make.py	Wed Dec 18 18:02:26 2013 +0100
@@ -4,10 +4,10 @@
 import os
 
 def make_kernel():
+    import zcc
     arglist = ['memory.c3', 'kernel.c3', 'syscall.c3', 'process.c3']
     arglist += ['schedule.c3', 'arch_arm.c3']
     arglist += ['--target', 'arm']
-    arglist += ['--dumpasm', '--dumpir']
     arglist += ['--log', 'debug']
 
     args = zcc.parser.parse_args(arglist)
@@ -15,5 +15,4 @@
 
 if __name__ == '__main__':
     sys.path.insert(0, os.path.join('..', 'python'))
-    import zcc
     make_kernel()
--- a/python/ppci/c3/codegenerator.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/python/ppci/c3/codegenerator.py	Wed Dec 18 18:02:26 2013 +0100
@@ -34,7 +34,7 @@
         self.pkg = pkg
         self.intType = pkg.scope['int']
         self.boolType = pkg.scope['bool']
-        self.logger.info('Generating ir-code for {}'.format(pkg.name))
+        self.logger.info('Generating ir-code for {}'.format(pkg.name), extra={'c3_ast':pkg})
         self.varMap = {}    # Maps variables to storage locations.
         self.funcMap = {}
         self.m = ir.Module(pkg.name)
@@ -48,7 +48,8 @@
                 self.gen_function(s)
         except SemanticError as e:
             self.error(e.msg, e.loc)
-        return self.m
+        if self.pkg.ok:
+            return self.m
 
     def error(self, msg, loc=None):
         self.pkg.ok = False
@@ -70,16 +71,14 @@
 
         for sym in fn.innerScope:
             # TODO: handle parameters different
+            self.checkType(sym.typ)
             if sym.isParameter:
-                self.checkType(sym.typ)
                 variable = ir.Parameter(sym.name)
                 f.addParameter(variable)
             elif sym.isLocal:
-                self.checkType(sym.typ)
                 variable = ir.LocalVariable(sym.name)
                 f.addLocal(variable)
             elif isinstance(sym, ast.Variable):
-                self.checkType(sym.typ)
                 variable = ir.LocalVariable(sym.name)
                 f.addLocal(variable)
             else:
@@ -222,13 +221,16 @@
                 raise NotImplementedError('Unknown unop {0}'.format(expr.op))
         elif type(expr) is ast.Identifier:
             # Generate code for this identifier.
-            expr.lvalue = True
             tg = self.resolveSymbol(expr)
             expr.kind = type(tg)
             expr.typ = tg.typ
             # This returns the dereferenced variable.
             if isinstance(tg, ast.Variable):
+                expr.lvalue = True
                 return ir.Mem(self.varMap[tg])
+            elif isinstance(tg, ast.Constant):
+                c_val = self.genExprCode(tg.value)
+                return self.evalConst(c_val)
             else:
                 raise NotImplementedError(str(tg))
         elif type(expr) is ast.Deref:
@@ -261,7 +263,7 @@
             return ir.Mem(ir.Add(base.e, offset))
         elif type(expr) is ast.Literal:
             expr.lvalue = False
-            typemap = {int: 'int', float: 'double', bool: 'bool'}
+            typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'}
             if type(expr.val) in typemap:
                 expr.typ = self.pkg.scope[typemap[type(expr.val)]]
             else:
@@ -312,6 +314,12 @@
         expr.typ = ftyp.returntype
         return ir.Call(fname, args)
 
+    def evalConst(self, c):
+        if isinstance(c, ir.Const):
+            return c
+        else:
+            raise SemanticError('Cannot evaluate constant {}'.format(c))
+
     def resolveSymbol(self, sym):
         if type(sym) is ast.Member:
             base = self.resolveSymbol(sym.base)
--- a/python/ppci/c3/parser.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/python/ppci/c3/parser.py	Wed Dec 18 18:02:26 2013 +0100
@@ -155,6 +155,7 @@
             self.Consume('=')
             val = self.Expression()
             c = Constant(name.val, t, val)
+            self.addDeclaration(c)
             c.loc = name.loc
             if not self.hasConsumed(','):
                 break
--- a/python/ppci/c3/visitor.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/python/ppci/c3/visitor.py	Wed Dec 18 18:02:26 2013 +0100
@@ -59,6 +59,7 @@
         elif type(node) is Deref:
             self.do(node.ptr)
         elif type(node) is Constant:
+            self.do(node.typ)
             self.do(node.value)
         elif type(node) is DefinedType:
             self.do(node.typ)
@@ -86,13 +87,14 @@
 
 class AstPrinter:
     """ Prints an AST as text """
-    def printAst(self, pkg):
-        self.indent = 0
+    def printAst(self, pkg, f):
+        self.indent = 2
+        self.f = f
         visitor = Visitor()
         visitor.visit(pkg, self.print1, self.print2)
 
     def print1(self, node):
-        print(' ' * self.indent + str(node))
+        print(' ' * self.indent + str(node), file=self.f)
         self.indent += 2
 
     def print2(self, node):
--- a/python/ppci/codegen/interferencegraph.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/python/ppci/codegen/interferencegraph.py	Wed Dec 18 18:02:26 2013 +0100
@@ -41,6 +41,7 @@
                     n.live_out = set.union(*(s.live_in for s in n.Succ))
                 else:
                     n.live_out = set()
+                n.live_out = n.live_out | n.defs
                 change = change or (_in != n.live_in) or (_out != n.live_out)
 
         # Construct interference graph:
--- a/python/zcc.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/python/zcc.py	Wed Dec 18 18:02:26 2013 +0100
@@ -4,7 +4,7 @@
 import argparse
 import logging
 
-from ppci.c3 import Builder
+from ppci.c3 import Builder, AstPrinter
 import ppci
 from ppci.irutils import Verifier, Writer
 from ppci.codegen import CodeGenerator
@@ -33,6 +33,16 @@
 
     def format(self, record):
         s = super().format(record)
+        if hasattr(record, 'c3_ast'):
+            f = io.StringIO()
+            print('', file=f)
+            print('', file=f)
+            print('.. code::', file=f)
+            print('', file=f)
+            AstPrinter().printAst(record.c3_ast, f)
+            #Writer('  ').write(record.c3_ast, f)
+            print('', file=f)
+            s += '\n' + f.getvalue()
         if hasattr(record, 'ircode'):
             f = io.StringIO()
             print('', file=f)
@@ -90,7 +100,6 @@
   help='Possible import module', action='append', default=[])
 
 parser.add_argument('--dumpir', action='store_true', help="Dump IR-code")
-parser.add_argument('--dumpasm', action='store_true', help="Dump ASM-code")
 parser.add_argument('--optimize', action='store_true', help="Optimize")
 parser.add_argument('--target', help="Backend selection",
     choices=targetnames, required=True)
@@ -119,14 +128,12 @@
     for ircode in c3b.build(srcs, imps):
         if not ircode:
             return
+
+        d = {'ircode':ircode}
+        logging.info('Verifying code {}'.format(ircode), extra=d)
         # Optimization passes, TODO
         Verifier().verify(ircode)
 
-        if dumpir:
-            f = io.StringIO()
-            irutils.Writer().write(ircode, f)
-            print(f.getvalue())
-
         # Code generation:
         d = {'ircode':ircode}
         logging.info('Starting code generation for {}'.format(ircode), extra=d)
@@ -138,11 +145,11 @@
 
 
 def main(args):
-    logging.basicConfig(format=logformat, level=args.log)
+    #logging.getLogger().setLevel(logging.DEBUG)
     #logging.getLogger().addHandler(RstLogHandler())
-    fh = logging.FileHandler('log.rst', mode='w')
-    fh.setFormatter(RstFormatter())
-    logging.getLogger().addHandler(fh)
+    #fh = logging.FileHandler('log.rst', mode='w')
+    #fh.setFormatter(RstFormatter())
+    #logging.getLogger().addHandler(fh)
 
     tg = targets[args.target]
     diag = ppci.DiagnosticsManager()
@@ -153,8 +160,7 @@
         diag.printErrors()
         return 1
 
-    if args.dumpasm:
-        outs.dump()
+    logging.info('Assembly created', extra={'zcc_outs':outs})
 
     code_bytes = outs.sections['code'].to_bytes()
     if args.output:
--- a/test/testc3.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/test/testc3.py	Wed Dec 18 18:02:26 2013 +0100
@@ -98,6 +98,24 @@
         """
         self.expectOK([p1, p2])
 
+    def testConstant(self):
+        snip = """module C;
+        const int a = 2;
+        """
+        i = self.expectOK(snip)
+
+    @unittest.skip('Not checked yet')
+    def testConstantMutual(self):
+        snip = """module C;
+        const int a = b + 1;
+        const int b = a + 1;
+        function void f()
+        {
+          return b;
+        }
+        """
+        i = self.expectOK(snip)
+
     def testPackageNotExists(self):
         p1 = """module p1;
         import p23;
--- a/test/testzcc.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/test/testzcc.py	Wed Dec 18 18:02:26 2013 +0100
@@ -37,16 +37,16 @@
     def testKernel(self):
         # Build kernel using zcc:
         kerneldir = os.path.normpath(os.path.join('..', 'kernel'))
-        sys.path.insert(0, kerneldir) 
+        sys.path.insert(0, kerneldir)
         from make import make_kernel
         os.chdir(kerneldir)
         make_kernel()
         sys.path.pop(-1)
-        
+
     def testUser(self):
         # Build userspace using zcc:
         userdir = os.path.normpath(os.path.join('..', 'user'))
-        sys.path.insert(0, userdir) 
+        sys.path.insert(0, userdir)
         from makeuser import make_user
         os.chdir(userdir)
         make_user()
@@ -80,4 +80,4 @@
 
 
 if __name__ == '__main__':
-    unittest.main()
\ No newline at end of file
+    unittest.main()
--- a/user/hello.c3	Mon Dec 16 17:58:15 2013 +0100
+++ b/user/hello.c3	Wed Dec 18 18:02:26 2013 +0100
@@ -7,6 +7,6 @@
 
 function void start()
 {
-    lib.print('Hello space');
+    lib.print(9); // 'Hello space');
 }
 
--- a/user/ipc.c3	Mon Dec 16 17:58:15 2013 +0100
+++ b/user/ipc.c3	Wed Dec 18 18:02:26 2013 +0100
@@ -1,13 +1,26 @@
 
 module ipc;
 
+type struct {
+    int sender;
+    int data;
+} Msg;
+
+const int MSG_SEND=1;
+const int MSG_RECV=2;
+
+function int kernelTrap(int msgId, int a, int b)
+{
+    // TODO: make this in assembler?
+}
+
 function void SendMessage(Msg *msg)
 {
-    kernelTrap(MSG_SEND, msg)
+    kernelTrap(MSG_SEND, 1, 0)
 }
 
 function void RecvMessage(Msg msg)
 {
-    kernelTrap(MSG_RECV, msg);
+    kernelTrap(MSG_RECV, 2, 0);
 }
 
--- a/user/lib.c3	Mon Dec 16 17:58:15 2013 +0100
+++ b/user/lib.c3	Wed Dec 18 18:02:26 2013 +0100
@@ -5,7 +5,7 @@
 
 */
 
-function void print(string txt)
+function void print(int txt)
 {
     // TODO
 }
--- a/user/makeuser.py	Mon Dec 16 17:58:15 2013 +0100
+++ b/user/makeuser.py	Wed Dec 18 18:02:26 2013 +0100
@@ -7,7 +7,6 @@
 def make_user():
     arglist = ['lib.c3', 'ipc.c3', 'hello.c3']
     arglist += ['--target', 'arm']
-    arglist += ['--dumpasm', '--dumpir']
     arglist += ['--log', 'debug']
 
     args = zcc.parser.parse_args(arglist)