РЕДАКТИРОВАТЬ3 После повторного изучения этой проблемы я обнаружил большую проблему с этим подходом.Прежде всего, некоторые пояснения: Coco / R генерирует сканер и парсер из файла atg, основная программа в Taste.cs использует их для компиляции Taste.TAS.
Скомпилированный Taste.TAS затем передается в метод Interpret CodeGen.cs, который обрабатывает коды операций, которые он получает как виртуальная машина, поэтому этот метод ReadInt()
должен считывать из Taste.IN,примеры данных для скомпилированной программы Taste.TAS.
Итак, чтобы добавить поддержку hello world в CodeGen.cs, недостаточно изменить метод Interpret, вам нужно будет исправить метод Emit.также, чтобы позволить компилятору добавить строку во время компиляции.
Hacky как всегда (идет в CodeGen.cs):
List<string> strStack = new List<string>();
public void Emit(Op op, string str)
{
int idx = strStack.Count;
strStack.Add(str);
Emit(op, idx); // adds the opcode,
}
В Taste.ATG у вас будетчтобы изменить инструкцию записи на Gen.Emit(Op.WRITES, t.val);
А в методе Interpret вам нужно будет использовать ссылку на список строк:
case Op.WRITES: Console.WriteLine(strStack[Next2()]); break;
EDIT4 - Justдля дальнейшего использования Чтобы прочитать строковый литерал из файла, вы можете использовать класс StreamReader
, например, так:
/// <summary>
/// Reads a string literal from a file, essentially implementing the regex pattern /\"{.*}\"/.
/// Ignores escape characters (for instance, "\"" will fail)
/// </summary>
/// <param name="fs">The file stream to read from.</param>
/// <returns>The string literal without it's quotes upon success, null otherwise.</returns>
static string ReadString(FileStream fs)
{
if (!fs.CanRead)
return null; // cant read from stream, throw an exception here
var reader = new StreamReader(fs);
var sb = new StringBuilder();
bool inString = false;
while (true)
{
if (reader.Peek() < 0)
return null; // reached EOF before string ended, throw exception here
char ch = (char)reader.Read();
if (inString)
if (ch == '"')
break;
else
sb.Append(ch);
else
if (ch == '"')
inString = true;
else if (!char.IsWhiteSpace(ch))
return null; // string does not start with quote, throw exception here
}
return sb.ToString();
}
Альтернативой может быть использование [Regex
] [3] класс, но так как он по умолчанию работает только сстрок, требуются некоторые хитрые операции чтения и поиска для получения строк, занимающих несколько строк (если поддерживается), поэтому вы не добавляете поток файлов для остальной части программы.