-
Notifications
You must be signed in to change notification settings - Fork 1
/
DCC.cs
118 lines (95 loc) · 4.12 KB
/
DCC.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
///<summary>
///Main class and entry point for the C compiler.
///</summary>
///<author>Radu Vasilecu</author>
///<date>2019-03-29</date>
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace dcc {
class dcc {
static void Main(string[] args) {
System.Console.WriteLine("\nDuke 250/16 C Compiler version 1.0 - Radu Vasilescu, 2019\n");
if (args.Length == 0) {
System.Console.WriteLine();
ShowHelpText();
return;
}
bool verbose = false;
bool printPreproc = false;
bool enableStrout = true;
string sourceFile = "";
foreach (string arg in args) {
if (arg == "-v" || arg == "--verbose") {
verbose = true;
} else if (arg == "-h" || arg == "--help") {
ShowHelpText();
Environment.Exit(0);
} else if (arg == "-p" || arg == "--pre-processor") {
printPreproc = true;
} else if (arg == "--disable-strout") {
enableStrout = false;
} else {
sourceFile = arg;
}
}
// Read the source file
string[] sourceStr;
List<string> source = null;
try {
sourceStr = File.ReadAllLines(sourceFile);
source = sourceStr.OfType<string>().ToList();
} catch (Exception e) {
Console.Error.WriteLine("Error: " + e.Message);
Environment.Exit(1);
}
// Run the pre-processor
source = Preprocessor.ProcessAll(source, enableStrout);
if (printPreproc) PrintSource(source);
// Tokenize the source
Tokenizer toker = new Tokenizer();
List<Token> tokenized = null;
try {
tokenized = toker.Tokenize(source);
} catch (Tokenizer.TokenException e) {
Console.Error.WriteLine("Error: " + e.Message);
Environment.Exit(1);
}
if (verbose) System.Console.WriteLine("Parsing...");
// Parse the tokenized program into a collection of Abstract Source Trees
Parser parser = new Parser(tokenized);
AbstractProgram parsedProgram = parser.Parse();
if (verbose) System.Console.WriteLine("Done parsing.");
// Generate and emit assembly instructions
Emitter emitter = new Emitter(parsedProgram);
List<string> outputCode = emitter.EmitAssembly();
if (verbose) System.Console.WriteLine("Done emitting.");
if (verbose) {
System.Console.WriteLine("\nAssembly: \n");
foreach (string line in outputCode) {
System.Console.WriteLine(line);
}
}
string outputFile = sourceFile.Split(".")[0] + ".s";
string outputCodeStr = String.Join("\n", outputCode);
File.WriteAllText(outputFile, outputCodeStr);
if (verbose) System.Console.WriteLine("\nOutput stored in: " + outputFile);
}
private static void PrintSource(List<string> source) {
for (int i = 0; i < source.Count; i++) {
System.Console.WriteLine(source[i]);
}
}
static void ShowHelpText() {
System.Console.WriteLine("Usage: dcc [-v | --verbose] program.c");
System.Console.WriteLine();
System.Console.WriteLine("Options: ");
System.Console.WriteLine(" -h --help Display this help message.");
System.Console.WriteLine(" -v --verbose Print steps and progress, and output the");
System.Console.WriteLine(" assembled result to the console.");
System.Console.WriteLine();
}
}
}