コード例 #1
0
        private static void MakeLoopEnd(TokenizerOutput program, TLine line, Stack <LoopData> loopStack)
        {
            if (loopStack.Count < 1)
            {
                throw new TokenizerException(line, "Misplaced NEXT");
            }

            LoopData data = loopStack.Pop();
            var      next = (KwNext)line.Statement;

            if (data.LoopVariable.Name != next.Variable.Name)
            {
                throw new TokenizerException(line, "NEXT Error : Unknown variable " + next.Variable.Name);
            }

            // step 1: change the variable
            var add    = new NumBinaryOperator(data.LoopVariable, data.StepVariable, "+");
            var assign = new NumBinaryOperator(data.LoopVariable, add, "=");

            program.Program.Add(line.Clone(assign));

            // step 2: goto to the begining
            var gt = new KwrGoto(data.StartLine, true);

            program.Program.Add(line.Clone(gt));

            // change the top jump condition
            ((KwrJumpIfTrue)program.Program[data.StartLine].Statement).JumpPos = program.Program.Count;
        }
コード例 #2
0
        private static LoopData MakeLoopBegin(TokenizerOutput program, TLine line)
        {
            var kwFor = (KwFor)line.Statement;
            var ret   = new LoopData {
                StartLine = (program.Program.Count + 2)
            };

            // step 1: var = initial
            NumVariable forVar = kwFor.Variable;

            program.Program.Add(line.Clone(new NumBinaryOperator(forVar, kwFor.Initial, "=")));
            ret.LoopVariable = forVar;

            // step 2: make step variable
            var          stepVar   = new NumVariable("$" + ret.StartLine + forVar.Name + "_StepVariable");
            NumStatement stepValue = kwFor.Step ?? new NumConstant("1");

            program.Program.Add(line.Clone(new NumBinaryOperator(stepVar, stepValue, "=")));
            ret.StepVariable = stepVar;

            // step 3: loop
            var condition = new NumBoolBinaryOperator(forVar, kwFor.End, ">");
            var jmp       = new KwrJumpIfTrue(condition, -1);

            program.Program.Add(line.Clone(jmp));

            return(ret);
        }
コード例 #3
0
        private static void MakeBranch(TokenizerOutput program, TLine line, Stack <LoopData> loopStack)
        {
            var kwif  = (KwIf)line.Statement;
            var newIf = new KwrJumpIfNotTrue(kwif.Condition, -1);

            program.Program.Add(line.Clone(newIf));                 // placeholder

            foreach (Statement s in kwif.Statements)
            {
                TokenizeStatement(program, line.Clone(s), loopStack);
            }

            if (kwif.ElseStatements == null)
            {
                newIf.JumpPos = program.Program.Count;
            }
            else
            {
                var gt = new KwrGoto(-1, true);
                program.Program.Add(line.Clone(gt));
                newIf.JumpPos = program.Program.Count;

                foreach (Statement s in kwif.ElseStatements)
                {
                    TokenizeStatement(program, line.Clone(s), loopStack);
                }

                gt.JumpPos = program.Program.Count;
            }
        }
コード例 #4
0
        private static void TokenizeStatement(TokenizerOutput program, TLine line, Stack <LoopData> loopStack)
        {
            if (line.Statement is KwGoto)
            {
                program.Program.Add(line.Clone(new KwrGoto(((KwGoto)line.Statement).Value.Value, false)));
            }
            else if (line.Statement is KwGosub)
            {
                program.Program.Add(line.Clone(new KwrGosub(((KwGosub)line.Statement).Value.Value, false)));
            }
            else if (line.Statement is KwData)
            {
                KwData data = (KwData)line.Statement;

                if (program.Data == null)
                {
                    program.Data = new List <string>();
                }

                ((List <string>)program.Data).AddRange(data.Data);
                program.Program.Add(line.Clone(new KwRem(line.OriginalLine.OriginalLine)));
            }
            else if (line.Statement is KwIf)
            {
                MakeBranch(program, line, loopStack);
            }
            else if (line.Statement is KwFor)
            {
                LoopData d = MakeLoopBegin(program, line);
                loopStack.Push(d);
            }
            else if (line.Statement is KwNext)
            {
                MakeLoopEnd(program, line, loopStack);
            }
            else if (line.Statement is KwOn)
            {
                MakeOnStatement(program, line);
            }
            else if (line.Statement is KwPrint)
            {
                MakePrintStatement(program, line);
            }
            else if (line.Statement is KwDim)
            {
                KwDim dim = (KwDim)line.Statement;
                foreach (VariableArray arr in dim.ArrayList)
                {
                    program.Program.Add(line.Clone(new KwrDim(arr)));
                }
            }
            else
            {
                program.Program.Add(line);
            }
        }
コード例 #5
0
        private static void MakeOnStatement(TokenizerOutput program, TLine line)
        {
            var kw = (KwOn)line.Statement;

            for (int j = 0; j < kw.JumpList.Count; ++j)
            {
                var cnd = new NumBoolBinaryOperator(kw.Statement, new NumConstant((j + 1).ToString()), "==");
                var ifc = new KwrJumpIfNotTrue(cnd, -1);
                program.Program.Add(line.Clone(ifc));

                int     jumpPos = kw.JumpList[j].Value;
                KwrJump jmp     = kw.Kind == KwOn.OnKind.Goto ? new KwrGoto(jumpPos, false) : (KwrJump) new KwrGosub(jumpPos, false);
                program.Program.Add(line.Clone(jmp));

                ifc.JumpPos = program.Program.Count;
            }
        }
コード例 #6
0
        private static IList <TLine> Normalize(IEnumerable <Line> lines)
        {
            var prog = new List <Line>(lines);

            prog.Sort((a, b) => Comparer <int?> .Default.Compare(a.LineNum, b.LineNum));
            var ret = new List <TLine>();

            foreach (Line line in prog)
            {
                foreach (Statement stat in line.Statements)
                {
                    TLine newLine = new TLine(line, stat);
                    ret.Add(newLine);
                }
            }

            return(ret);
        }
コード例 #7
0
        private static void MakePrintStatement(TokenizerOutput program, TLine line)
        {
            var print = (KwPrint)line.Statement;

            if (print.PrintList == null)
            {
                program.Program.Add(line.Clone(new KwrPrint(new StringConstant(""), true)));
                return;
            }

            foreach (KwPrint.Group group in print.PrintList)
            {
                bool newLine = String.IsNullOrEmpty(group.EndChar);
                program.Program.Add(line.Clone(new KwrPrint(group.Statement, newLine)));

                if (!newLine && group.EndChar == ",")
                {
                    program.Program.Add(line.Clone(new KwrPrint(new StringConstant("\t"), false)));
                }
            }
        }
コード例 #8
0
 public TokenizerException(TLine line, string message) : base(message)
 {
     Line = line;
 }
コード例 #9
0
        private static TokenizerOutput Tokenize(IErrorPrinter errorPrinter, IEnumerable <TLine> program)
        {
            var ret = new TokenizerOutput {
                Program = new List <TLine>()
            };

            var positions = new Dictionary <int, int>();
            var loopStack = new Stack <LoopData>();

            try {
                foreach (var line in program)
                {
                    int ln = line.OriginalLine.LineNum.Value;
                    if (!positions.ContainsKey(ln))
                    {
                        positions.Add(ln, ret.Program.Count);
                    }

                    TokenizeStatement(ret, line, loopStack);
                }

                ret.Program.Add(new TLine(new Line(), new KwEnd()));
            }
            catch (TokenizerException e) {
                Console.WriteLine("ERROR!");
                Console.WriteLine("Line " + e.Line.OriginalLine.OriginalLinePosition + " : " + e.Line.OriginalLine.OriginalLine);
                Console.WriteLine(e.Message);
                ret = null;
            }

            if (ret == null)
            {
                return(null);
            }

            // check jumps
            for (int i = 0; i < ret.Program.Count; ++i)
            {
                TLine cmd = ret.Program[i];
                var   gt  = cmd.Statement as KwrJump;
                if (gt != null)
                {
                    if (!gt.Normalized)
                    {
                        if (!positions.ContainsKey(gt.JumpPos))
                        {
                            throw new TokenizerException(new TLine(cmd.OriginalLine, cmd.OriginalLine.Statements[0]), "Invalid jump");
                        }

                        gt.JumpPos    = positions[gt.JumpPos];
                        gt.Normalized = true;
                    }

                    if (gt is KwrGosub)
                    {
                        ((KwrGosub)gt).ReturnAddress = i + 1;
                    }
                }
            }

            return(ret);
        }