Showing
4 changed files
with
33 additions
and
11 deletions
... | @@ -69,7 +69,7 @@ tokens = ( | ... | @@ -69,7 +69,7 @@ tokens = ( |
69 | 'DOUBLE_MINUS', | 69 | 'DOUBLE_MINUS', |
70 | 'PLUS', | 70 | 'PLUS', |
71 | 'MINUS', | 71 | 'MINUS', |
72 | - 'TIMES', | 72 | +# 'TIMES', |
73 | 'DIV', | 73 | 'DIV', |
74 | 'MODULO', | 74 | 'MODULO', |
75 | 'DOUBLE_AMPERSAND', | 75 | 'DOUBLE_AMPERSAND', |
... | @@ -169,7 +169,7 @@ t_DOUBLE_PLUS = r'\+\+' | ... | @@ -169,7 +169,7 @@ t_DOUBLE_PLUS = r'\+\+' |
169 | t_DOUBLE_MINUS = r'--' | 169 | t_DOUBLE_MINUS = r'--' |
170 | t_PLUS = r'\+' | 170 | t_PLUS = r'\+' |
171 | t_MINUS = r'-' | 171 | t_MINUS = r'-' |
172 | -t_TIMES = r'\*' | 172 | +# t_TIMES = r'\*' |
173 | t_DIV = r'/(?!\*)' | 173 | t_DIV = r'/(?!\*)' |
174 | t_MODULO = r'%' | 174 | t_MODULO = r'%' |
175 | t_DOUBLE_AMPERSAND = r'&&' | 175 | t_DOUBLE_AMPERSAND = r'&&' | ... | ... |
... | @@ -755,9 +755,7 @@ def p_empty(t): | ... | @@ -755,9 +755,7 @@ def p_empty(t): |
755 | pass | 755 | pass |
756 | 756 | ||
757 | def p_error(t): | 757 | def p_error(t): |
758 | - print("You've got a syntax error somewhere in your code.") | 758 | + print("[%s:%s] syntax error" % (t.lineno, t.lexpos)) |
759 | - print("It could be around line %d." % t.lineno) | ||
760 | - print("Good luck finding it.") | ||
761 | raise ParseError() | 759 | raise ParseError() |
762 | 760 | ||
763 | yacc.yacc(debug=1) | 761 | yacc.yacc(debug=1) | ... | ... |
... | @@ -2,6 +2,15 @@ import argparse, sys, os.path | ... | @@ -2,6 +2,15 @@ import argparse, sys, os.path |
2 | 2 | ||
3 | import ply.yacc as yacc | 3 | import ply.yacc as yacc |
4 | from . import cparse, cvisitors, cx86 | 4 | from . import cparse, cvisitors, cx86 |
5 | +cttc = cx86 | ||
6 | + | ||
7 | +ARCH = {"x86" : cx86, | ||
8 | + "ttc" : cttc} | ||
9 | + | ||
10 | +ARCHDOC = """supported target architectures: | ||
11 | + x86 Intel 80x86 assembly (in GNU Assemble format) | ||
12 | + ttc The Tiny Computer assembly | ||
13 | +""" | ||
5 | 14 | ||
6 | class CompileError (Exception) : | 15 | class CompileError (Exception) : |
7 | "Exception raised when there's been a compilation error." | 16 | "Exception raised when there's been a compilation error." |
... | @@ -11,7 +20,8 @@ class Compiler (object) : | ... | @@ -11,7 +20,8 @@ class Compiler (object) : |
11 | """This object encapsulates the front-end for the compiler and | 20 | """This object encapsulates the front-end for the compiler and |
12 | serves as a facade interface to the 'meat' of the compiler | 21 | serves as a facade interface to the 'meat' of the compiler |
13 | underneath.""" | 22 | underneath.""" |
14 | - def __init__ (self) : | 23 | + def __init__ (self, arch) : |
24 | + self.arch = arch | ||
15 | self.total_errors = 0 | 25 | self.total_errors = 0 |
16 | self.total_warnings = 0 | 26 | self.total_warnings = 0 |
17 | def _parse (self) : | 27 | def _parse (self) : |
... | @@ -31,12 +41,15 @@ class Compiler (object) : | ... | @@ -31,12 +41,15 @@ class Compiler (object) : |
31 | self._compile_phase(cvisitors.SymtabVisitor()) | 41 | self._compile_phase(cvisitors.SymtabVisitor()) |
32 | self._compile_phase(cvisitors.TypeCheckVisitor()) | 42 | self._compile_phase(cvisitors.TypeCheckVisitor()) |
33 | self._compile_phase(cvisitors.FlowControlVisitor()) | 43 | self._compile_phase(cvisitors.FlowControlVisitor()) |
34 | - self._compile_phase(cx86.CodeGenVisitor(outfile)) | 44 | + self._compile_phase(self.arch.CodeGenVisitor(outfile)) |
35 | if ast_file is not None: | 45 | if ast_file is not None: |
36 | self._compile_phase(cvisitors.ASTPrinterVisitor(ast_file)) | 46 | self._compile_phase(cvisitors.ASTPrinterVisitor(ast_file)) |
37 | def _print_stats (self) : | 47 | def _print_stats (self) : |
38 | "Prints the total number of errors/warnings from compilation." | 48 | "Prints the total number of errors/warnings from compilation." |
39 | - print("%d errors, %d warnings." % (self.total_errors, self.total_warnings)) | 49 | + if self.total_errors : |
50 | + print("%d errors" % self.total_errors) | ||
51 | + if self.total_warnings : | ||
52 | + print("%s warnings" % self.total_warnings) | ||
40 | def compile (self, code, outfile, show_ast) : | 53 | def compile (self, code, outfile, show_ast) : |
41 | "Compiles the given code string to the given file object." | 54 | "Compiles the given code string to the given file object." |
42 | self.code = code | 55 | self.code = code |
... | @@ -54,21 +67,32 @@ class Compiler (object) : | ... | @@ -54,21 +67,32 @@ class Compiler (object) : |
54 | return 0 | 67 | return 0 |
55 | 68 | ||
56 | def main (args=None) : | 69 | def main (args=None) : |
57 | - parser = argparse.ArgumentParser(prog="cct") | 70 | + parser = argparse.ArgumentParser(prog="cct", |
71 | + epilog=ARCHDOC, | ||
72 | + formatter_class=argparse.RawDescriptionHelpFormatter) | ||
58 | parser.add_argument("-o", action="store", metavar="PATH", | 73 | parser.add_argument("-o", action="store", metavar="PATH", |
59 | type=argparse.FileType('w'), default=sys.stdout, | 74 | type=argparse.FileType('w'), default=sys.stdout, |
60 | help="write output to PATH") | 75 | help="write output to PATH") |
61 | parser.add_argument("--ast", action="store_true", default=False, | 76 | parser.add_argument("--ast", action="store_true", default=False, |
62 | help="dump AST for each C file") | 77 | help="dump AST for each C file") |
78 | + parser.add_argument("--arch", action="store", choices=list(ARCH), | ||
79 | + default="ttc", | ||
80 | + help="output assembly for specified architecture (default 'ttc')") | ||
81 | + parser.add_argument("-t", "--ttc", action="store_const", const="ttc", | ||
82 | + dest="arch", help="output TTC assembly") | ||
63 | parser.add_argument("source", nargs="+", metavar="PATH", | 83 | parser.add_argument("source", nargs="+", metavar="PATH", |
64 | help="C source files(s) to compile") | 84 | help="C source files(s) to compile") |
65 | args = parser.parse_args(args) | 85 | args = parser.parse_args(args) |
66 | for src in args.source : | 86 | for src in args.source : |
87 | + print("Compiling %r" % src) | ||
67 | if args.ast : | 88 | if args.ast : |
68 | - ast_file = open(os.path.splitext(src)[0] + ".ast", "w") | 89 | + ast_path = os.path.splitext(src)[0] + ".ast" |
90 | + print("Dumping AST to %r" % ast_path) | ||
91 | + ast_file = open(ast_path, "w") | ||
69 | else : | 92 | else : |
70 | ast_file = None | 93 | ast_file = None |
71 | - retval = Compiler().compile(open(src).read(), args.o, ast_file) | 94 | + code = "\n".join(open(src).readlines()) |
95 | + retval = Compiler(ARCH[args.arch]).compile(code, args.o, ast_file) | ||
72 | if ast_file is not None : | 96 | if ast_file is not None : |
73 | ast_file.close() | 97 | ast_file.close() |
74 | if retval != 0 : | 98 | if retval != 0 : | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment