コード例 #1
0
ファイル: Environment.cs プロジェクト: user202729/EsotericIDE
        public void NumericOperation(Func <BigInteger, BigInteger, object> intInt, Func <double, double, object> doubleDouble)
        {
            var item2 = ScliptingUtil.ToNumeric(Pop());
            var item1 = ScliptingUtil.ToNumeric(Pop());

            if (item1 is double)
            {
                if (item2 is double)
                {
                    CurrentStack.Add(doubleDouble((double)item1, (double)item2));
                }
                else
                {
                    CurrentStack.Add(doubleDouble((double)item1, (double)(BigInteger)item2));
                }
            }
            else
            {
                if (item2 is double)
                {
                    CurrentStack.Add(doubleDouble((double)(BigInteger)item1, (double)item2));
                }
                else
                {
                    CurrentStack.Add(intInt((BigInteger)item1, (BigInteger)item2));
                }
            }
        }
コード例 #2
0
ファイル: Environment.cs プロジェクト: user202729/EsotericIDE
        public void GenerateOutput()
        {
            var index = CurrentStack.Count;

            while (index > 0 && !(CurrentStack[index - 1] is Mark))
            {
                index--;
            }
            for (; index < CurrentStack.Count; index++)
            {
                _output.Append(ScliptingUtil.ToString(CurrentStack[index]));
            }
        }
コード例 #3
0
ファイル: Environment.cs プロジェクト: user202729/EsotericIDE
        public void NumericOperation(Func <BigInteger, object> fromInt, Func <double, object> fromDouble)
        {
            var item = ScliptingUtil.ToNumeric(Pop());

            if (item is double)
            {
                CurrentStack.Add(fromDouble((double)item));
            }
            else
            {
                CurrentStack.Add(fromInt((BigInteger)item));
            }
        }
コード例 #4
0
        private static void findMatchingEnd(string source, int start, int addIndex, out int?conditionEndIndex, out int?elseIndex, out bool elsePops, out int endIndex)
        {
            conditionEndIndex = null;
            elseIndex         = null;
            elsePops          = false;
            var         depth = 0;
            Instruction instruction;
            NodeType    type;

            for (int i = start; i < source.Length; i++)
            {
                if (ScliptingUtil.GetInstructionInfo(source[i], out instruction, out type))
                {
                    if (type == NodeType.BlockHead)
                    {
                        depth++;
                    }
                    else if (type == NodeType.BlockConditionEnd && depth == 1)
                    {
                        if (conditionEndIndex != null)
                        {
                            throw new CompileException("“{0}” block cannot have multiple condition-block instructions.".Fmt(source[start]), start + addIndex, i - start + addIndex + 1);
                        }
                        conditionEndIndex = i;
                    }
                    else if (type == NodeType.BlockElse && depth == 1)
                    {
                        if (elseIndex != null)
                        {
                            throw new CompileException("“{0}” block cannot have multiple else-block instructions.".Fmt(source[start]), start + addIndex, i - start + addIndex + 1);
                        }
                        elseIndex = i;
                        elsePops  = source[i] == '不';
                    }
                    else if (type == NodeType.BlockEnd)
                    {
                        depth--;
                        if (depth == 0)
                        {
                            endIndex = i;
                            return;
                        }
                    }
                }
            }
            throw new CompileException("Block instruction “{0}” is missing a matching end instruction.".Fmt(source[start]), start + addIndex, 1);
        }
コード例 #5
0
ファイル: Environment.cs プロジェクト: user202729/EsotericIDE
        private string describe(object item)
        {
            byte[]        b;
            List <object> list;
            Function      fnc;

            if ((b = item as byte[]) != null)
            {
                return("Byte array: “{0}” ({1})".Fmt(b.FromUtf8().CLiteralEscape(), ScliptingUtil.ToInt(b)));
            }
            else if (item is BigInteger)
            {
                return("Integer: {0}".Fmt(item));
            }
            else if (item is string)
            {
                return("String: “{0}”".Fmt(((string)item).CLiteralEscape()));
            }
            else if (item is double)
            {
                return("Float: {0}".Fmt(ExactConvert.ToString((double)item)));
            }
            else if (item is Mark)
            {
                return("Mark");
            }
            else if ((list = item as List <object>) != null)
            {
                return("List ({0} items)".Fmt(list.Count) + list.Select((itm, idx) => Environment.NewLine + describe(itm, idx)).JoinString().Indent(4, false));
            }
            else if ((fnc = item as Function) != null)
            {
                return("Function" + (fnc.CapturedItem != null ? "; capture: " + describe(fnc.CapturedItem) : "; no capture"));
            }

            // unknown type of object?
            return("{0} ({1})".Fmt(item, item.GetType().FullName));
        }
コード例 #6
0
ファイル: Parser.cs プロジェクト: schifflee/EsotericIDE
        public static List <Node> Parse(string source, int addIndex)
        {
            Instruction           instruction;
            NodeType              type;
            ListStringInstruction listStringType;
            bool backwards;

            var ret   = new List <Node>();
            int index = 0;

            while (index < source.Length)
            {
                var ch = source[index];
                if (ch < 0x0100)
                {
                    // can wlite comments using infeliol Amelican and Eulopean chalactels
                    index++;
                }
                else if (ch >= 0xac00 && ch < 0xbc00)
                {
                    // Beginning of byte allay
                    var origIndex = index;
                    var hangeul   = ParseByteArrayToken(source, index);
                    index += hangeul.Length;
                    try
                    {
                        ret.Add(new ByteArray {
                            Array = ScliptingUtil.DecodeByteArray(hangeul), Index = origIndex + addIndex, Count = index - origIndex
                        });
                    }
                    catch (CompileException ce)
                    {
                        throw new CompileException(ce.Message, ce.Index + origIndex + addIndex, ce.Length);
                    }
                }
                else if (ch >= 0xbc00 && ch <= 0xd7a3)
                {
                    ret.Add(new NegativeNumber {
                        Number = 0xbbff - ch, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '①' && ch <= '⑳')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.CopyFromBottom, Value = ch - '①' + 1, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '㉑' && ch <= '㉟')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.CopyFromBottom, Value = ch - '㉑' + 21, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '㊱' && ch <= '㊿')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.CopyFromBottom, Value = ch - '㊱' + 36, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '⓵' && ch <= '⓾')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.MoveFromTop, Value = ch - '⓵' + 1, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '❶' && ch <= '❿')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.CopyFromTop, Value = ch - '❶' + 1, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '⓫' && ch <= '⓴')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.CopyFromTop, Value = ch - '⓫' + 11, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '⑴' && ch <= '⒇')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.MoveFromBottom, Value = ch - '⑴' + 1, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= '⒈' && ch <= '⒛')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.SwapFromBottom, Value = ch - '⒈' + 1, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ch >= 'Ⓐ' && ch <= 'Ⓩ')
                {
                    ret.Add(new StackOrRegexNode {
                        Type = StackOrRegexNodeType.RegexCapture, Value = ch - 'Ⓐ' + 1, Index = index++ + addIndex, Count = 1
                    });
                }
                else if (ListStringElementNode.Characters.Contains(ch))
                {
                    ret.Add(new ListStringElementNode(ch, index++ + addIndex));
                }
                else if (ScliptingUtil.GetInstructionInfo(ch, out listStringType, out backwards))
                {
                    ret.Add(new ListStringElementNode(listStringType, backwards, index++ + addIndex));
                }
                else if (ScliptingUtil.GetInstructionInfo(ch, out instruction, out type))
                {
                    switch (type)
                    {
                    case NodeType.SingularNode:
                        ret.Add(new SingularNode {
                            ThisInstruction = instruction, Index = index++ + addIndex, Count = 1
                        });
                        break;

                    case NodeType.FunctionExecutionNode:
                        ret.Add(new ExecuteFunction {
                            Instruction = instruction, Index = index++ + addIndex, Count = 1
                        });
                        break;

                    case NodeType.BlockHead:
                        int? conditionEndIndex;
                        int? elseIndex;
                        bool elsePops;
                        int  endIndex;
                        findMatchingEnd(source, index, addIndex, out conditionEndIndex, out elseIndex, out elsePops, out endIndex);
                        var         primaryBlock   = Parse(source.Substring(index + 1, (conditionEndIndex ?? elseIndex ?? endIndex) - index - 1), index + 1 + addIndex);
                        List <Node> conditionBlock = null;
                        if (conditionEndIndex != null)
                        {
                            conditionBlock = primaryBlock;
                            primaryBlock   = Parse(source.Substring(conditionEndIndex.Value + 1, (elseIndex ?? endIndex) - conditionEndIndex.Value - 1), conditionEndIndex.Value + 1 + addIndex);
                        }
                        var elseBlock  = elseIndex == null ? null : Parse(source.Substring(elseIndex.Value + 1, endIndex - elseIndex.Value - 1), elseIndex.Value + 1 + addIndex);
                        var blockInstr = BlockNode.Create(ch, instruction, index, addIndex, conditionEndIndex, elseIndex, elsePops);
                        blockInstr.PrimaryBlock      = primaryBlock;
                        blockInstr.ConditionBlock    = conditionBlock;
                        blockInstr.ConditionEndIndex = (conditionEndIndex ?? 0) + addIndex;
                        blockInstr.ElseBlock         = elseBlock;
                        blockInstr.ElseBlockPops     = elsePops;
                        blockInstr.Index             = index + addIndex;
                        blockInstr.Count             = endIndex - index + 1;
                        blockInstr.ElseIndex         = (elseIndex ?? 0) + addIndex;
                        ret.Add(blockInstr);
                        index = endIndex + 1;
                        break;

                    case NodeType.BlockElse:
                    case NodeType.BlockEnd:
                        throw new CompileException("Else or end instruction encountered without a matching block head instruction.", index + addIndex, 1);

                    default:
                        throw new CompileException("Unrecognised instruction: “{0}”.".Fmt(ch), index + addIndex, 1);
                    }
                }
                else
                {
                    throw new CompileException("Unrecognised instruction: “{0}”.".Fmt(ch), index + addIndex, 1);
                }
            }
            return(ret);
        }