예제 #1
0
        private void BeginRoutine()
        {
            if (_posTokens.Count != 2)
            {
                throw new ApplicationException(); // todo2[ak]
            }

            if (_currentRoutine != null)
            {
                throw new ApplicationException(); // todo2[ak]
            }

            string routineName = ((SymbolToken)_posTokens[1]).Name;
            _currentRoutine = new RoutineBuilder(routineName);
            this.AdvanceLine();
        }
예제 #2
0
        private List<Routine> CompileLines(string[] lines)
        {
            _lines = lines;
            _pos = 0;
            _currentRoutine = null;

            List<RoutineBuilder> routineBuilders = new List<RoutineBuilder>();

            while (true)
            {
                if (this.IsEnd())
                {
                    break;
                }

                string line = this.GetCurrentLine();
                _posTokens = _tokenizer.Tokenize(line);

                if (_posTokens.Count == 0)
                {
                    this.AdvanceLine();
                    continue;
                }

                Token first = _posTokens[0];
                if (first is SymbolToken)
                {
                    SymbolToken symb = (SymbolToken)first;
                    if (symb.Name == DECL_ROUTINE)
                    {
                        this.BeginRoutine();
                    }
                    else
                    {
                        if (_currentRoutine == null)
                        {
                            throw new ApplicationException(); // todo2[ak]
                        }

                        InstructionBuilder ib = this.GetInstructionBuilder(symb.Name);

                        if (ib == null)
                        {
                            if (symb.Name == DECL_END)
                            {
                                bool ok =
                                    _posTokens.Count == 2 &&
                                    _posTokens[1] is SymbolToken &&
                                    ((SymbolToken)_posTokens[1]).Name == DECL_ROUTINE;

                                if (ok)
                                {
                                    // end of routine
                                    _currentRoutine.Finish();
                                    routineBuilders.Add(_currentRoutine);
                                    _currentRoutine = null;
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }
                            else
                            {
                                // label ?
                                if (_posTokens.Count == 2 && _posTokens[1] == ColonToken.Value)
                                {
                                    // label!
                                    _currentRoutine.AddLabel(symb.Name);
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }
                        }
                        else
                        {
                            var args = this.ExtractArgs(_posTokens.Skip(1));

                            //_currentRoutine.AddInstruction(ib, _posTokens.Skip(1).ToArray());
                            _currentRoutine.AddInstruction(ib, args);
                        }

                        this.AdvanceLine();
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            List<Routine> routines = routineBuilders
                .Select(b => b.Build())
                .ToList();

            return routines;
        }