Franck Pommereau

added insertion of external libraries

...@@ -7,10 +7,10 @@ def _lnomap (line) : ...@@ -7,10 +7,10 @@ def _lnomap (line) :
7 except : 7 except :
8 pass 8 pass
9 9
10 -def cpp (path, arch, args) : 10 +def cpp (path, args) :
11 lmap = {} 11 lmap = {}
12 code = [] 12 code = []
13 - args = ["cpp", "-D__CCT__", "-D__CCT_%s__" % arch] + args + [path] 13 + args = ["cpp", "-D__CCT__"] + args + [path]
14 pos = 1 14 pos = 1
15 out = subprocess.check_output(args) 15 out = subprocess.check_output(args)
16 for line in (l.rstrip() for l in out.decode().splitlines()) : 16 for line in (l.rstrip() for l in out.decode().splitlines()) :
......
1 -import io, os.path 1 +import io, os.path, re
2 2
3 from . import cparse 3 from . import cparse
4 from .cvisitors import Visitor 4 from .cvisitors import Visitor
...@@ -123,12 +123,14 @@ class CodeGenVisitor (Visitor) : ...@@ -123,12 +123,14 @@ class CodeGenVisitor (Visitor) :
123 def __init__(self, path, test=None): 123 def __init__(self, path, test=None):
124 Visitor.__init__(self) 124 Visitor.__init__(self)
125 self.path = path 125 self.path = path
126 + self._lbl = re.sub("[^a-z0-9]", "", os.path.splitext(path)[0],
127 + flags=re.I)
126 self.test = test 128 self.test = test
127 self.str_literal_str = io.StringIO() 129 self.str_literal_str = io.StringIO()
128 self.str_literal_dict = {} 130 self.str_literal_dict = {}
129 131
130 def new_label(self): 132 def new_label(self):
131 - label = "_L%d" % self.__label 133 + label = "_%s_L%d" % (self._lbl, self.__label)
132 self.__class__.__label += 1 134 self.__class__.__label += 1
133 return label 135 return label
134 136
...@@ -181,21 +183,22 @@ class CodeGenVisitor (Visitor) : ...@@ -181,21 +183,22 @@ class CodeGenVisitor (Visitor) :
181 self._visitList(node.nodes) 183 self._visitList(node.nodes)
182 184
183 @classmethod 185 @classmethod
184 - def concat (cls, outfile, chunks) : 186 + def concat (cls, boot, outfile, chunks) :
185 outfile.write("# Generated by cct\n" 187 outfile.write("# Generated by cct\n"
186 "# Franck Pommereau (2018)\n" 188 "# Franck Pommereau (2018)\n"
187 "# Adapted from Atul Varma's c.py (Spring 2004)\n\n") 189 "# Adapted from Atul Varma's c.py (Spring 2004)\n\n")
188 - outfile.write("#\n" 190 + if boot :
189 - "# on computer start: call main and halt\n" 191 + outfile.write("#\n"
190 - "#\n\n" 192 + "# on computer start: call main and halt\n"
191 - "IRQ0:\n" 193 + "#\n\n"
192 - " set R9 @main\n" 194 + "IRQ0:\n"
193 - " call R9\n" 195 + " set R9 @%s\n"
194 - " halt\n") 196 + " call R9\n"
197 + " halt\n\n" % boot)
195 for c in chunks : 198 for c in chunks :
196 s = c.curr_str.getvalue() 199 s = c.curr_str.getvalue()
197 if s.strip() : 200 if s.strip() :
198 - outfile.write("\n#\n# code from file %r\n#\n" % c.path) 201 + outfile.write("#\n# code from file %r\n#\n" % c.path)
199 outfile.write(s) 202 outfile.write(s)
200 for c in chunks : 203 for c in chunks :
201 s = c.globals_str.getvalue() 204 s = c.globals_str.getvalue()
...@@ -366,7 +369,7 @@ class CodeGenVisitor (Visitor) : ...@@ -366,7 +369,7 @@ class CodeGenVisitor (Visitor) :
366 if str in self.str_literal_dict : 369 if str in self.str_literal_dict :
367 return self.str_literal_dict[str] 370 return self.str_literal_dict[str]
368 371
369 - label_str = "_LC%d" % self.__str_literal_label 372 + label_str = "_%s_LC%d" % (self._lbl, self.__str_literal_label)
370 self.str_literal_dict[str] = label_str 373 self.str_literal_dict[str] = label_str
371 str = str.replace('\n', '\\n') 374 str = str.replace('\n', '\\n')
372 self.str_literal_str.write("""%s:\n str "%s\\0"\n""" % (label_str, str)) 375 self.str_literal_str.write("""%s:\n str "%s\\0"\n""" % (label_str, str))
......
This diff is collapsed. Click to expand it.
1 import argparse, sys, os, os.path, subprocess 1 import argparse, sys, os, os.path, subprocess
2 2
3 import ply.yacc as yacc 3 import ply.yacc as yacc
4 -from . import cparse, cvisitors, cx86, cttc, cpp 4 +from . import cparse, cvisitors, cttc, cpp
5 -
6 -ARCH = {"x86" : cx86,
7 - "ttc" : cttc}
8 -
9 -ARCHDOC = """supported target architectures:
10 - x86 Intel 80x86 assembly (in GNU Assemble format)
11 - ttc The Tiny Computer assembly
12 -"""
13 5
14 class CompileError (Exception) : 6 class CompileError (Exception) :
15 "Exception raised when there's been a compilation error." 7 "Exception raised when there's been a compilation error."
...@@ -19,8 +11,7 @@ class Compiler (object) : ...@@ -19,8 +11,7 @@ class Compiler (object) :
19 """This object encapsulates the front-end for the compiler and 11 """This object encapsulates the front-end for the compiler and
20 serves as a facade interface to the 'meat' of the compiler 12 serves as a facade interface to the 'meat' of the compiler
21 underneath.""" 13 underneath."""
22 - def __init__ (self, arch, path, lmap, test) : 14 + def __init__ (self, path, lmap, test) :
23 - self.arch = arch
24 self.path = path 15 self.path = path
25 self.lmap = lmap 16 self.lmap = lmap
26 self.test = test 17 self.test = test
...@@ -45,7 +36,7 @@ class Compiler (object) : ...@@ -45,7 +36,7 @@ class Compiler (object) :
45 self._compile_phase(cvisitors.SymtabVisitor()) 36 self._compile_phase(cvisitors.SymtabVisitor())
46 self._compile_phase(cvisitors.TypeCheckVisitor()) 37 self._compile_phase(cvisitors.TypeCheckVisitor())
47 self._compile_phase(cvisitors.FlowControlVisitor()) 38 self._compile_phase(cvisitors.FlowControlVisitor())
48 - comp = self.arch.CodeGenVisitor(self.path, self.test) 39 + comp = cttc.CodeGenVisitor(self.path, self.test)
49 self._compile_phase(comp) 40 self._compile_phase(comp)
50 if ast_file is not None: 41 if ast_file is not None:
51 self._compile_phase(cvisitors.ASTPrinterVisitor(ast_file)) 42 self._compile_phase(cvisitors.ASTPrinterVisitor(ast_file))
...@@ -74,7 +65,6 @@ class Compiler (object) : ...@@ -74,7 +65,6 @@ class Compiler (object) :
74 65
75 def main (args=None) : 66 def main (args=None) :
76 parser = argparse.ArgumentParser(prog="cct", 67 parser = argparse.ArgumentParser(prog="cct",
77 - epilog=ARCHDOC,
78 formatter_class=argparse.RawDescriptionHelpFormatter) 68 formatter_class=argparse.RawDescriptionHelpFormatter)
79 parser.add_argument("-o", action="store", metavar="PATH", 69 parser.add_argument("-o", action="store", metavar="PATH",
80 type=argparse.FileType('w'), default=sys.stdout, 70 type=argparse.FileType('w'), default=sys.stdout,
...@@ -83,13 +73,16 @@ def main (args=None) : ...@@ -83,13 +73,16 @@ def main (args=None) :
83 help="dump AST for each C file") 73 help="dump AST for each C file")
84 parser.add_argument("--cpp", "-p", action="store_true", default=False, 74 parser.add_argument("--cpp", "-p", action="store_true", default=False,
85 help="process input file through cpp") 75 help="process input file through cpp")
86 - parser.add_argument("--arch", action="store", choices=list(ARCH), default="ttc",
87 - help="output assembly for specified architecture"
88 - " (default 'ttc')")
89 parser.add_argument("--compile", "-c", action="store_true", default=False, 76 parser.add_argument("--compile", "-c", action="store_true", default=False,
90 help="compile generated ASM") 77 help="compile generated ASM")
91 parser.add_argument("--test", "-t", action="store_true", default=False, 78 parser.add_argument("--test", "-t", action="store_true", default=False,
92 help="test compiler") 79 help="test compiler")
80 + parser.add_argument("--boot", "-b", nargs=1, metavar="FUNC",
81 + help="boot machine by calling FUNC")
82 + parser.add_argument("-L", dest="libpath", metavar="DIR", action="append", default=[],
83 + help="add DIR to the directories to be searched for -l")
84 + parser.add_argument("-l", dest="libs", metavar="LIB", action="append", default=[],
85 + help="include LIB in the generated code")
93 parser.add_argument("source", nargs="+", metavar="PATH", 86 parser.add_argument("source", nargs="+", metavar="PATH",
94 help="C source files(s) to compile") 87 help="C source files(s) to compile")
95 args = parser.parse_args(args) 88 args = parser.parse_args(args)
...@@ -110,24 +103,39 @@ def main (args=None) : ...@@ -110,24 +103,39 @@ def main (args=None) :
110 ast_file = None 103 ast_file = None
111 if args.cpp : 104 if args.cpp :
112 print("Preprocessing %r" % src) 105 print("Preprocessing %r" % src)
113 - cppargs = ARCH[args.arch].cpp(args) 106 + cppargs = cttc.cpp(args)
114 print("..$ cpp %s %s" % (" ".join(cppargs), src)) 107 print("..$ cpp %s %s" % (" ".join(cppargs), src))
115 - code, lmap = cpp.cpp(src, args.arch, cppargs) 108 + code, lmap = cpp.cpp(src, cppargs)
116 print("Compiling preprocessed %r" % src) 109 print("Compiling preprocessed %r" % src)
117 else : 110 else :
118 code = "\n".join(l.rstrip() for l in open(src).readlines()) 111 code = "\n".join(l.rstrip() for l in open(src).readlines())
119 lmap = {} 112 lmap = {}
120 print("Compiling %r" % src) 113 print("Compiling %r" % src)
121 - ret = Compiler(ARCH[args.arch], src, lmap, args.test).compile(code, ast_file) 114 + ret = Compiler(src, lmap, args.test).compile(code, ast_file)
122 if ast_file is not None : 115 if ast_file is not None :
123 ast_file.close() 116 ast_file.close()
124 if ret is None : 117 if ret is None :
125 sys.exit(1) 118 sys.exit(1)
126 chunks.append(ret) 119 chunks.append(ret)
127 - ARCH[args.arch].CodeGenVisitor.concat(args.o, chunks) 120 + if args.boot :
121 + boot = args.boot[0]
122 + else :
123 + boot = None
124 + cttc.CodeGenVisitor.concat(boot, args.o, chunks)
125 + for lib in args.libs :
126 + for base in ["."] + args.libpath :
127 + path = os.path.join(base, lib + ".asm")
128 + if os.path.exists(path) :
129 + print("Appending %r" % path)
130 + args.o.write("\n#\n# lib %r\n#\n" % path)
131 + args.o.write(open(path).read())
132 + break
133 + else :
134 + print("Library %r not found" % lib)
135 + sys.exit(1)
128 args.o.flush() 136 args.o.flush()
129 if args.compile : 137 if args.compile :
130 - tgt, cmd = ARCH[args.arch].compile(args.o.name) 138 + tgt, cmd = cttc.compile(args.o.name)
131 print("Building %r" % tgt) 139 print("Building %r" % tgt)
132 print(".. $ %s" % " ".join(cmd)) 140 print(".. $ %s" % " ".join(cmd))
133 ret = subprocess.run(cmd) 141 ret = subprocess.run(cmd)
......
1 all: 1 all:
2 - python3 ../cct.py --arch=ttc -p -o stdio-c.asm stdio.c 2 + python3 ../cct.py -p -l stdio_putc -o stdio.asm stdio.c
3 - cat stdio_putc.asm > stdio.asm
4 - tail -n +14 stdio-c.asm >> stdio.asm
......
This diff is collapsed. Click to expand it.
1 +#include "stdio.h"
2 +
3 +#define UCHAR 117
4 +#define XCHAR 120
5 +
6 +int main() {
7 + puts("hello world\n");
8 + putu(42, XCHAR);
9 + puts(" => 2A\n");
10 + putu(42, UCHAR);
11 + puts(" => 42\n");
12 + puti(42);
13 + puts(" => 42\n");
14 + puti(-42);
15 + puts(" => -42\n");
16 + printf("hello %s I'm %u (%x)\n", "stdio", 42, 42);
17 + return 0;
18 +}
This diff is collapsed. Click to expand it.
1 -// CCT compiler with TTC backend 1 +// CCT compiler
2 -#ifdef __CCT_ttc__ 2 +#ifdef __CCT__
3 extern int putc(char c); 3 extern int putc(char c);
4 #define neg(i) -i 4 #define neg(i) -i
5 #define UINT(i) i 5 #define UINT(i) i
6 #define _DIGITS "0123456789ABCDEF" 6 #define _DIGITS "0123456789ABCDEF"
7 #define _STR "65536" 7 #define _STR "65536"
8 -#endif
9 -
10 -// CCT compiler with x86 backend
11 -#ifdef __CCT_x86__
12 -extern int putchar(int c);
13 -#define putc(c) putchar(c)
14 -#define neg(i) -i
15 -#define UINT(i) i
16 -#define _DIGITS "0123456789ABCDEF"
17 -#define _STR "65536"
18 -#endif
19 -
20 // regular compiler 8 // regular compiler
21 -#ifndef __CCT__ 9 +#else
22 extern int putchar(int c); 10 extern int putchar(int c);
23 #define putc(c) putchar(c) 11 #define putc(c) putchar(c)
24 #define neg(i) ~i + 1 12 #define neg(i) ~i + 1
...@@ -84,14 +72,13 @@ int putu(int u, char f) { ...@@ -84,14 +72,13 @@ int putu(int u, char f) {
84 72
85 int puti(int i) { 73 int puti(int i) {
86 int n; 74 int n;
87 - n = 0;
88 if (UINT(i) > 32767) { 75 if (UINT(i) > 32767) {
89 - n += putc(MINUS); 76 + n = putc(MINUS);
90 n += putu(neg(i), UCHAR); 77 n += putu(neg(i), UCHAR);
91 - return n;
92 } else { 78 } else {
93 - return putu(i, UCHAR); 79 + n = putu(i, UCHAR);
94 } 80 }
81 + return n;
95 } 82 }
96 83
97 int printf(char *str, ...) { 84 int printf(char *str, ...) {
...@@ -134,17 +121,3 @@ int printf(char *str, ...) { ...@@ -134,17 +121,3 @@ int printf(char *str, ...) {
134 } 121 }
135 return n; 122 return n;
136 } 123 }
137 -
138 -/* int main() { */
139 -/* puts("hello world\n"); */
140 -/* putu(42, XCHAR); */
141 -/* puts(" => 2A\n"); */
142 -/* putu(42, UCHAR); */
143 -/* puts(" => 42\n"); */
144 -/* puti(42); */
145 -/* puts(" => 42\n"); */
146 -/* puti(-42); */
147 -/* puts(" => -42\n"); */
148 -/* printf("hello %s I'm %u (%x)\n", "stdio", 42, 42); */
149 -/* return 0; */
150 -/* } */
......