162 lines
4.4 KiB
C#
162 lines
4.4 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace arookas
|
|
{
|
|
static class SSC {
|
|
static void Main(string[] args) {
|
|
Message("ssc v0.1 arookas\n");
|
|
var cmd = new CommandLine(args);
|
|
if (cmd.Count == 0) {
|
|
Message("Usage: ssc -input <input.sun> [-output <output.sb>]\n");
|
|
Pause();
|
|
Exit(1);
|
|
}
|
|
var compiler = new sunCompiler();
|
|
int exitCode = 0;
|
|
string inputFile, outputFile;
|
|
ReadCmdLine(cmd, out inputFile, out outputFile);
|
|
using (var output = OpenOutput(outputFile)) {
|
|
var results = compiler.Compile(inputFile, output);
|
|
if (results.Success) {
|
|
Message("Finished compiling in {0:F2}ms.\n", results.CompileTime.TotalMilliseconds);
|
|
Message(" Data count: {0}\n", results.DataCount);
|
|
Message("Symbol count: {0}\n", results.SymbolCount);
|
|
Message(" - builtins: {0}\n", results.BuiltinCount);
|
|
Message(" - functions: {0}\n", results.FunctionCount);
|
|
Message(" - variables: {0}\n", results.VariableCount);
|
|
}
|
|
else {
|
|
if (results.Error is sunSourceException) {
|
|
var error = results.Error as sunSourceException;
|
|
Error(" in file \"{0}\"\n at line {1}, col {2}\n\n{3}{4}", error.Location.File, error.Location.Line, error.Location.Column, GetErrorPreview(error.Location), error.Message);
|
|
exitCode = 1;
|
|
}
|
|
else {
|
|
var error = results.Error;
|
|
Error("{0}", error.Message);
|
|
exitCode = 1;
|
|
}
|
|
}
|
|
}
|
|
Pause();
|
|
Exit(exitCode);
|
|
}
|
|
|
|
static Stream OpenOutput(string path) {
|
|
try {
|
|
return File.Create(path);
|
|
}
|
|
catch {
|
|
Error("Failed to create output file '{0}'.", path);
|
|
Pause();
|
|
Exit(1);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// command-line
|
|
static void ReadCmdLine(CommandLine cmd, out string inputFile, out string outputFile) {
|
|
inputFile = null;
|
|
outputFile = null;
|
|
foreach (var prm in cmd) {
|
|
switch (prm.Name) {
|
|
case "-input": GetInput(prm, ref inputFile); break;
|
|
case "-output": GetOutput(prm, ref outputFile); break;
|
|
}
|
|
}
|
|
if (inputFile == null) {
|
|
Error("Missing -input option.\n");
|
|
Pause();
|
|
Exit(1);
|
|
}
|
|
if (outputFile == null) {
|
|
outputFile = Path.ChangeExtension(inputFile, ".sb");
|
|
}
|
|
}
|
|
static void GetInput(CommandLineParameter prm, ref string inputFile) {
|
|
if (inputFile != null) {
|
|
Error("Only one -input option is allowed.\n");
|
|
Pause();
|
|
Exit(1);
|
|
}
|
|
if (prm.Count != 1) {
|
|
Error("Incorrect number of arguments in -input option.\n");
|
|
Pause();
|
|
Exit(1);
|
|
}
|
|
inputFile = prm[0];
|
|
}
|
|
static void GetOutput(CommandLineParameter prm, ref string outputFile) {
|
|
if (outputFile != null) {
|
|
Error("Only one -output option is allowed.\n");
|
|
Pause();
|
|
Exit(1);
|
|
}
|
|
if (prm.Count != 1) {
|
|
Error("Incorrect number of arguments in -output option.\n");
|
|
Pause();
|
|
Exit(1);
|
|
}
|
|
outputFile = prm[0];
|
|
}
|
|
|
|
// error preview
|
|
static string GetErrorPreview(sunSourceLocation location) {
|
|
Stream file;
|
|
try {
|
|
file = File.OpenRead(location.File);
|
|
}
|
|
catch {
|
|
// simply don't do a preview if opening a file fails
|
|
return "";
|
|
}
|
|
using (var reader = new StreamReader(file)) {
|
|
// skip to line
|
|
for (var line = 1; line < location.Line; ++line) {
|
|
reader.ReadLine();
|
|
}
|
|
// generate column string
|
|
var sb = new StringBuilder();
|
|
var preview = reader.ReadLine();
|
|
sb.AppendLine(preview);
|
|
for (var column = 1; column < location.Column; ++column) {
|
|
var c = preview[column - 1];
|
|
if (IsFullWidth(c)) {
|
|
sb.Append(" "); // full-width hack
|
|
}
|
|
else if (c == '\t') {
|
|
sb.Append('\t');
|
|
}
|
|
else {
|
|
sb.Append(" ");
|
|
}
|
|
}
|
|
sb.Append("^");
|
|
sb.Append("\n");
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
static bool IsFullWidth(char c) { return (c >= 0x2E80 && c <= 0x9FFF) || (c >= 0xFF00 && c <= 0xFFEF); }
|
|
|
|
// output
|
|
static void Message(string format, params object[] args) { Console.Write(format, args); }
|
|
static void Warning(string format, params object[] args) {
|
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
|
Console.Write("WARNING:\n");
|
|
Message(format, args);
|
|
Console.ResetColor();
|
|
}
|
|
static void Error(string format, params object[] args) {
|
|
Console.ForegroundColor = ConsoleColor.Red;
|
|
Console.Write("ERROR:\n");
|
|
Message(format, args);
|
|
Console.ResetColor();
|
|
}
|
|
|
|
[Conditional("DEBUG")] static void Pause() { Console.ReadKey(); }
|
|
static void Exit(int code) { Environment.Exit(code); }
|
|
}
|
|
}
|