Exemplo n.º 1
0
 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 ' ';
 }
Exemplo n.º 2
0
        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;
            }
        }
Exemplo n.º 3
0
        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, ' '));
        }
Exemplo n.º 4
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);
 }