public static char GetRuneChar(IExecutableRune rune) { foreach (KeyValuePair<char, IExecutableRune> pair in ALL_RUNES) { if (pair.Value == rune) return pair.Key; } if (rune is RuneCharLiteral) { return ((RuneCharLiteral) rune).c; } return ' '; }
public void SetRune(int x, int y, char c) { IExecutableRune r = RuneRegistry.GetRune(c); if (r == null) { runes[x, y] = new RuneCharLiteral(c); } else { runes[x, y] = r; } }
public static ParseError Parse(string v, string i, out RunicEnvironment context) { List <Vector2Int> entries = new List <Vector2Int>(); string code = v; inputStr = i; inputInd = 0; if (!code.Contains(";") && !code.Contains("F") && !code.Contains("@")) { context = null; return(new ParseError(ParseErrorType.NO_TERMINATOR, Vector2Int.zero, 0, ';')); } code = code.Replace("\r", string.Empty); string[] lines = code.Split('\n'); int max = 0; foreach (string s in lines) { string s2 = s; for (int x = s2.Length - 1; x >= 0; x--) { char cat = s2[x]; UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(cat); if (uc == UnicodeCategory.NonSpacingMark || uc == UnicodeCategory.EnclosingMark || uc == UnicodeCategory.OtherNotAssigned) { s2 = s2.Remove(x, 1); } } if (s2.Length > max) { max = s2.Length; } } //char[,] runesCodes = new char[max,lines.Length]; if (lines.Length == 1 && !(code.Contains("$") || code.Contains("@"))) { lines[0] = lines[0] + "@"; max++; } IExecutableRune[,] runes = new IExecutableRune[max, lines.Length]; char[,] modifiers = new char[max, lines.Length]; for (int y = 0; y < lines.Length; y++) { int mutateOffset = 0; for (int x = 0; x < max; x++) { char cat = (x + mutateOffset < lines[y].Length ? lines[y][x + mutateOffset] : ' '); if (cat == '\r') { cat = ' '; } IExecutableRune r = RuneRegistry.GetRune(cat); modifiers[x, y] = ' '; if (r == null) { runes[x, y] = new RuneCharLiteral(cat); } else { runes[x, y] = r; if (r is RuneEntrySimple /*&& (x == 0 || y == 0 || x == max - 1 || y == lines.Length - 1)*/) { char cat2 = (x + mutateOffset + 1 < lines[y].Length ? lines[y][x + mutateOffset + 1] : ' '); if ((cat == '<' || cat == '>') && cat2 == '̸') { if (cat == '<') { runes[x, y] = RuneRegistry.GetRune('('); } if (cat == '>') { runes[x, y] = RuneRegistry.GetRune(')'); } } else { entries.Add(new Vector2Int(x, y)); } } } while (x + mutateOffset + 1 < lines[y].Length) { char mod = lines[y][x + mutateOffset + 1]; UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(mod); if (uc == UnicodeCategory.NonSpacingMark || uc == UnicodeCategory.EnclosingMark || uc == UnicodeCategory.OtherNotAssigned) { if (modifiers[x, y] != ' ') { context = null; int p = modifiers.GetLength(0) * y + x; return(new ParseError(ParseErrorType.TOO_MANY_MODIFIERS, new Vector2Int(x, y), p, mod)); } IExecutableRune rr = runes[x, y]; if (rr is RuneReflector || rr is RuneReflectAll || rr is RuneDiagonalReflector || rr is RuneDirection) { context = null; int p = runes.GetLength(0) * y + x; return(new ParseError(ParseErrorType.INVALID_MODIFIER, new Vector2Int(x, y), p, mod)); } modifiers[x, y] = mod; mutateOffset++; } else { break; } } } } if (entries.Count == 0) { if (lines.Length == 1) { entries.Add(new Vector2Int(-1, 0)); } else { context = null; return(new ParseError(ParseErrorType.NO_ENTRY, Vector2Int.zero, 0, '>')); } } context = new RunicEnvironment(v, runes, entries, modifiers); context.SetReader(DefaultReader).SetWriter(context.GetDefaultWriter()); return(new ParseError(ParseErrorType.NONE, Vector2Int.zero, 0, ' ')); }
public bool Tick() { foreach (Pointer pointer in pointers) { bool delaying = pointer.GetDelayAmt() > 0; bool skipping = pointer.isSkipping(true); pointer.Execute(); if (pointer.GetReadType() == Pointer.ReadType.EXECUTE) { if (pointer.position.x >= runes.GetLength(0) || pointer.position.y >= runes.GetLength(1)) { pointer.DeductMana(pointer.GetMana()); } else if (skipping || delaying || runes[pointer.position.x, pointer.position.y].Execute(pointer, this)) { AdvancePointer(pointer, !delaying && !skipping); } } else if (pointer.GetReadType() == Pointer.ReadType.READ_NUM) { IExecutableRune r = runes[pointer.position.x, pointer.position.y]; if (r is RuneNumber) { int j = 0; int n = ((RuneNumber)r).value; if (pointer.GetStackSize() > 0) { object o = pointer.Pop(); if (o is ValueType && MathHelper.IsInteger((ValueType)o)) { j = (int)MathHelper.GetValue((ValueType)o); } } pointer.Push(j * 10 + n); AdvancePointer(pointer, false); } else { pointer.SetReadType(Pointer.ReadType.EXECUTE); } } else if (pointer.GetReadType() == Pointer.ReadType.READ_CHAR) { char c = RuneRegistry.GetRuneChar(runes[pointer.position.x, pointer.position.y]); pointer.Push(c); c = modifiers[pointer.position.x, pointer.position.y]; if (c != ' ') { pointer.Push(c); } pointer.SetReadType(Pointer.ReadType.EXECUTE); AdvancePointer(pointer, false); } else if (pointer.GetReadType() == Pointer.ReadType.READ_CHAR_CONTINUOUS) { char c = RuneRegistry.GetRuneChar(runes[pointer.position.x, pointer.position.y]); if (c.Equals('`')) { pointer.SetReadType(Pointer.ReadType.EXECUTE); } else { pointer.Push(c); c = modifiers[pointer.position.x, pointer.position.y]; if (c != ' ') { pointer.Push(c); } } AdvancePointer(pointer, false); } else if (pointer.GetReadType() == Pointer.ReadType.READ_STR) { char c = RuneRegistry.GetRuneChar(runes[pointer.position.x, pointer.position.y]); if (c.Equals('\"')) { pointer.SetReadType(Pointer.ReadType.EXECUTE); AdvancePointer(pointer, true); } else { object o = pointer.GetStackSize() > 0 ? pointer.Pop() : null; if (o is string || o == null) { string s = (string)o + c; c = modifiers[pointer.position.x, pointer.position.y]; if (c != ' ') { s += c; } pointer.Push(s); } else { pointer.Push(o); string s = c.ToString(); c = modifiers[pointer.position.x, pointer.position.y]; if (c != ' ') { s += c; } pointer.Push(s); } AdvancePointer(pointer, false); } } } pointers.ForEach(x => { int xi = pointers.IndexOf(x); pointers.ForEach(y => { int yi = pointers.IndexOf(y); if (xi < yi && x.position == y.position && x.direction == y.direction) { x.Merge(y); y.DeductMana(y.GetMana()); } }); }); pointers.ForEach(x => { if (x.GetMana() >= 100 && runes[x.position.x, x.position.y] != RuneRegistry.GetRune(' ')) { runes[x.position.x, x.position.y] = RuneRegistry.GetRune(' '); x.DeductMana(x.GetMana() / 2); Console.Error.WriteLine("Warning: rune at " + x.position + " has burned out!"); } }); pointers.ForEach(x => { if (modifiers[x.position.x, x.position.y] == '̺' || modifiers[x.position.x, x.position.y] == '̪') { if (x.GetStackSize() > x.GetMana() + 10) { TruncateStack(x, modifiers[x.position.x, x.position.y] == '̪'); } } }); pointers.ForEach(x => { if (x.GetStackSize() > x.GetMana() + 10) { x.DeductMana(1); } }); pointers.AddRange(newpointers); newpointers.Clear(); pointers.RemoveAll(x => x.GetMana() <= 0); return(pointers.Count > 0); }