changeset 204:de3a68f677a5

Added long comment to c3 parser
author Windel Bouwman
date Fri, 21 Jun 2013 15:01:08 +0200
parents ca1ea402f6a1
children d77cb5962cc5
files python/c3/__init__.py python/c3/codegenerator.py python/c3/lexer.py python/ir/builder.py python/ir/instruction.py python/repostats.py2 python/stm32f4/blink.c3 python/testc3.py python/testir.py python/zcc.py
diffstat 10 files changed, 129 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/python/c3/__init__.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/c3/__init__.py	Fri Jun 21 15:01:08 2013 +0200
@@ -1,3 +1,8 @@
+
+"""
+This is the C3 language front end.
+"""
+
 # Convenience imports:
 
 from .parser import Parser
--- a/python/c3/codegenerator.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/c3/codegenerator.py	Fri Jun 21 15:01:08 2013 +0200
@@ -19,7 +19,7 @@
       # Take care of forward declarations:
       for s in pkg.scope:
          if type(s) is astnodes.Function:
-            f = self.builder.newFunc(s.name)
+            f = self.builder.newFunction(s.name)
             self.funcMap[s] = f
       for s in pkg.scope:
          if type(s) is astnodes.Variable:
@@ -29,7 +29,7 @@
          elif type(s) is astnodes.Function:
             # TODO: handle arguments
             f = self.funcMap[s]
-            self.builder.setFunc(f)
+            self.builder.setFunction(f)
             bb = self.builder.newBB()
             f.entry = bb
             self.builder.setBB(bb)
@@ -45,7 +45,7 @@
             self.genCode(s.body)
             # TODO handle return?
             self.builder.addIns(ir.Return())
-            self.builder.setFunc(None)
+            self.builder.setFunction(None)
          else:
             print(s)
 
--- a/python/c3/lexer.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/c3/lexer.py	Fri Jun 21 15:01:08 2013 +0200
@@ -26,6 +26,8 @@
        ('NEWLINE', r'\n'),
        ('SKIP', r'[ \t]'),
        ('COMMENTS', r'//.*'),
+       ('LONGCOMMENTBEGIN', r'\/\*'),
+       ('LONGCOMMENTEND', r'\*\/'),
        ('LEESTEKEN', r'==|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}'),
        ('STRING', r"'.*?'")
      ]
@@ -34,16 +36,23 @@
      line = 1
      pos = line_start = 0
      mo = gettok(s)
+     incomment = False
      while mo is not None:
        typ = mo.lastgroup
        val = mo.group(typ)
        if typ == 'NEWLINE':
          line_start = pos
          line += 1
-       elif typ == 'COMMENTS':
+       elif typ == 'COMMENT':
          pass
+       elif typ == 'LONGCOMMENTBEGIN':
+          incomment = True
+       elif typ == 'LONGCOMMENTEND':
+          incomment = False
        elif typ == 'SKIP':
          pass
+       elif incomment:
+         pass # Wait until we are not in a comment section
        else:
          if typ == 'ID':
            if val in keywords:
--- a/python/ir/builder.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/ir/builder.py	Fri Jun 21 15:01:08 2013 +0200
@@ -43,11 +43,11 @@
       return bb
    def setModule(self, m):
       self.m = m
-   def newFunc(self, name):
+   def newFunction(self, name):
       f = Function(name)
       self.m.addFunc(f)
       return f
-   def setFunc(self, f):
+   def setFunction(self, f):
       self.fn = f
    def setBB(self, bb):
       self.bb = bb
--- a/python/ir/instruction.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/ir/instruction.py	Fri Jun 21 15:01:08 2013 +0200
@@ -16,6 +16,7 @@
 class Use:
    def __init__(self, user, val):
       self.user = user
+      assert type(val) is Value
       self.val = val
       self.val.used_by.append(self.user)
    def delete(self):
@@ -99,6 +100,7 @@
 class ImmLoad(Instruction):
    def __init__(self, target, value):
       super().__init__()
+      assert type(target) is Value
       self.target = target
       self.value = value
       self.addDef(target)
@@ -111,6 +113,8 @@
       super().__init__()
       #print('operation is in binops:', operation in BinOps)
       # Check types of the two operands:
+      assert type(value1) is Value
+      assert type(value2) is Value
       self.result = result
       self.addDef(result)
       self.value1 = value1
--- a/python/repostats.py2	Sat Jun 15 19:13:05 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#!/usr/bin/python2
-
-import sys
-# Use python 2 since mercurial does not support python 3 yet?
-assert sys.version_info.major == 2
-
-from mercurial import ui, hg
-import numpy
-import matplotlib.pyplot as plt
-import datetime
-
-u = ui.ui()
-repo = hg.repository(u, '..')
-
-stamps = []
-nds = repo.changelog.nodesbetween()[0]
-for hexid in nds:
-   cset = repo.changelog.read(hexid)
-   stamps.append(cset[2][0])
-
-dts = [datetime.datetime.fromtimestamp(st) for st in stamps]
-
-x = [dt.weekday() for dt in dts]
-y = [dt.hour for dt in dts]
-
-# plot it:
-f = plt.figure()
-#plt.hexbin(x, y)
-plt.scatter(x, y)
-ax = plt.gca()
-ax.set_ylim([0, 24])
-ax.set_ylabel('hour of day')
-ax.set_xlim([0, 7])
-ax.set_xlabel('day of week')
-ax.grid()
-plt.show()
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/stm32f4/blink.c3	Fri Jun 21 15:01:08 2013 +0200
@@ -0,0 +1,45 @@
+
+// This file blinks a LED on the STM32F4 discovery board.
+
+package blink;
+
+// Globals:
+var int divider;
+
+// Functions:
+function void tim2_handler()
+{
+    divider = 0;
+/*	if (TIM2->SR & TIM_SR_UIF)
+	{
+		divider++;
+		if (divider > 100000)
+		{
+			divider = 0;
+			GPIOD->ODR ^= (1 << 13);
+		}
+	}
+    */
+}
+
+function void main()
+{
+    divider = 0;
+    /*
+	RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
+	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
+	
+	GPIOD->MODER = (1<<26);
+	
+	NVIC->ISER[0] |= 1<< (TIM2_IRQn);
+	
+	TIM2->PSC = 0xE000;
+	TIM2->DIER |= TIM_DIER_UIE;
+	TIM2->ARR = 0xE000;
+	TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_CEN;
+	TIM2->EGR = 1;
+	
+	while(1);
+    */
+}
+
--- a/python/testc3.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/testc3.py	Fri Jun 21 15:01:08 2013 +0200
@@ -100,7 +100,26 @@
    diag = ppci.DiagnosticsManager()
    c3compile(testsrc, diag)
 
-class testA(unittest.TestCase):
+class testLexer(unittest.TestCase):
+    def testBlockComment(self):
+        snippet = """
+          /* Demo */
+          var int x = 0;
+        """
+        toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END']
+        self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks)
+    def testBlockCommentMultiLine(self):
+        snippet = """
+          /* Demo
+          bla1
+          bla2
+          */
+          var int x = 0;
+        """
+        toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END']
+        self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks)
+
+class testBuilder(unittest.TestCase):
    def setUp(self):
       self.diag = ppci.DiagnosticsManager()
       self.builder = c3.Builder(self.diag)
--- a/python/testir.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/testir.py	Fri Jun 21 15:01:08 2013 +0200
@@ -1,5 +1,30 @@
+import unittest, os
 import c3, ppci, ir, x86, transform
-import os
+
+class ConstantFolderTestCase(unittest.TestCase):
+    def setUp(self):
+        self.b = ir.Builder()
+        self.cf = transform.ConstantFolder()
+
+    def testBuilder(self):
+        m = ir.Module('test')
+        self.b.setModule(m)
+        f = self.b.newFunction('test')
+        self.b.setFunction(f)
+        bb = self.b.newBB()
+        self.b.setBB(bb)
+        v1 = self.b.newTmp('t')
+        v2 = self.b.newTmp('t')
+        v3 = self.b.newTmp('t')
+        self.b.addIns(ir.ImmLoad(v1, 5))
+        self.b.addIns(ir.ImmLoad(v2, 7))
+        self.b.addIns(ir.BinaryOperator(v3, '+', v1, v2))
+        self.assertEqual(3, len(m.Instructions))
+        self.cf.run(m)
+        self.assertEqual(3, len(m.Instructions))
+        self.assertIsInstance(m.Instructions[-1], ir.ImmLoad)
+        self.assertEqual(12, m.Instructions[-1].value)
+
 
 testsrc = """
 package test2;
@@ -50,6 +75,8 @@
 """
 
 if __name__ == '__main__':
+   unittest.main()
+   sys.exit()
    diag = ppci.DiagnosticsManager()
    builder = c3.Builder(diag)
    cgenx86 = x86.X86CodeGenSimple(diag)
--- a/python/zcc.py	Sat Jun 15 19:13:05 2013 +0200
+++ b/python/zcc.py	Fri Jun 21 15:01:08 2013 +0200
@@ -1,34 +1,21 @@
 #!/usr/bin/python
 
 import sys, os, argparse
-from ppci import core, frontends
+import c3, ppci
 
-parser = argparse.ArgumentParser(description='K# to bitcode compiler')
-parser.add_argument('source', type=str, help='the source file to build')
+parser = argparse.ArgumentParser(description='lcfos Compiler')
+parser.add_argument('source', type=argparse.FileType('r'), help='the source file to build')
 args = parser.parse_args()
 
-try:
-   with open(args.source, 'r') as f:
-      src = f.read()
-except IOError:
-   print('Failed to load {0}'.format(args.source))
-   sys.exit(1)
-print('stage 1: Parsing')
-# Create a context and a frontend:
-context = core.Context()
-frontend = frontends.KsFrontend(context)
-try:
-   module = frontend.compilesource(src)
-except core.CompilerException as e:
-   print(e)
-   lines = src.split(os.linesep)
-   row = e.row
-   col = e.col
-   line = lines[row - 1]
-   print('{0}:{1}'.format(row, line))
-   print(' ' * col + '^')
-   raise
-   #sys.exit(2)
+# Building:
+src = args.source.read()
+diag = ppci.DiagnosticsManager()
+c3b = c3.Builder(diag)
+
+ircode = c3b.build(src)
+if not ircode:
+    diag.printErrors(src)
+    sys.exit(1)
 
 # optionally run passes here:
 # TODO