Esempio n. 1
0
        public bool Parse(string code)
        {
            bool success = false;

            _scope    = new Stack <Scope>();
            _programm = new List <Scope>();
            _sp       = new Stack <Instruction>();
            uint        addr;
            string      vName;
            Instruction ri;

            try {
                global    = ScopePush(null);
                initBlock = new Scope(this, null, null);
                _programm.Add(initBlock);

                initBlock.AddInst(ri = new Instruction(EP_InstCode.LABEL));
                global.AddInst(EP_InstCode.NOP);
                global.AddInst(new Instruction(EP_InstCode.JMP)
                {
                    _ref = ri
                });
                global.AddInst(EP_InstCode.LABEL);

                dataBlock = new Scope(this, null, null);
                _programm.Add(dataBlock);

                var module = new Module(code, CompilerMessageCallback, Options.SuppressConstantPropogation | Options.SuppressUselessExpressionsElimination);

                if (module.Script.Root != null)
                {
                    var p1 = new EP_VP1(this);
                    module.Script.Root.Visit(p1);

                    _sp.Clear();
                    var p2 = new EP_VP2(this);
                    module.Script.Root.Visit(p2);
                }

                varList = new SortedList <string, string>();
                ioList  = new List <string>();
                uint mLen;

                addr = 0;
                var HexN = new SortedList <uint, byte[]>();

                foreach (var p in _programm)
                {
                    foreach (var m in p.memory.OrderBy(z => z.type))
                    {
                        switch (m.type)
                        {
                        case EP_Type.BOOL:
                            vName = "Mz";
                            mLen  = 1;
                            break;

                        case EP_Type.SINT8:
                            vName = "Mb";
                            mLen  = 8;
                            break;

                        case EP_Type.SINT16:
                            vName = "Mw";
                            mLen  = 16;
                            break;

                        case EP_Type.SINT32:
                            vName = "Md";
                            mLen  = 32;
                            break;

                        case EP_Type.UINT8:
                            vName = "MB";
                            mLen  = 8;
                            break;

                        case EP_Type.UINT16:
                            vName = "MW";
                            mLen  = 16;
                            break;

                        case EP_Type.REFERENCE:
                            vName = null;
                            mLen  = (uint)m.pOut * 32;
                            break;

                        case EP_Type.INPUT:
                        case EP_Type.OUTPUT:
                            ioList.Add(m.vd.Name);
                            continue;

                        default:
                            continue;
                        }
                        if (m.Addr == uint.MaxValue)
                        {
                            m.Addr = global.AllocateMemory(uint.MaxValue, mLen) / (mLen >= 32 ? 32 : mLen); //-V3064
                        }
                        if (p == global)
                        {
                            if (vName != null)
                            {
                                varList[m.vd.Name] = vName + m.Addr.ToString();
                                if (Verbose)
                                {
                                    Log.Debug("{0}<{1}> = {2}; {3}", m.vd.Name, m.type, vName + m.Addr.ToString(), mLen == 1?((m.Addr / 8).ToString("X2") + "." + (m.Addr % 8).ToString()):(m.Addr * mLen / 8).ToString("X2"));
                                }
                            }
                            else // REFERENCE
                            {
                                foreach (var m1 in m.scope.memory)
                                {
                                    switch (m1.type)
                                    {
                                    case EP_Type.PropB1:
                                        vName = "Mz";
                                        mLen  = 1;
                                        break;

                                    case EP_Type.PropS1:
                                        vName = "Mb";
                                        mLen  = 8;
                                        break;

                                    case EP_Type.PropS2:
                                        vName = "Mw";
                                        mLen  = 16;
                                        break;

                                    case EP_Type.PropS4:
                                        vName = "Md";
                                        mLen  = 32;
                                        break;

                                    case EP_Type.PropU1:
                                        vName = "MB";
                                        mLen  = 8;
                                        break;

                                    case EP_Type.PropU2:
                                        vName = "MW";
                                        mLen  = 16;
                                        break;

                                    default:
                                        continue;
                                    }
                                    varList[m.vd.Name + "." + m1.pName] = vName + (m.Addr * 32 / mLen + m1.Addr).ToString();
                                    if (Verbose)
                                    {
                                        Log.Debug("{0}<{1}> = {2}; {3}:{4}", m.vd.Name + "." + m1.pName, m1.type, vName + (m.Addr * 32 / mLen + m1.Addr).ToString()
                                                  , (m.Addr * 4).ToString("X2")
                                                  , mLen == 1?((m1.Addr / 8).ToString("X2") + "." + (m1.Addr % 8).ToString()):(m1.Addr * mLen / 8).ToString("X2"));
                                    }
                                }
                            }
                        }
                    }
                }
                foreach (var p in _programm)
                {
                    p.Optimize();
                    addr += (32 - (addr % 32)) % 32;
                    if (p.fm != null)
                    {
                        p.fm.Addr = addr;
                    }
                    foreach (var c in p.code)
                    {
                        c.Link(); // update size for LDI_*
                        c.addr = addr;
                        if (c._blob && c._param != null)
                        {
                            c._param.Addr = c.addr;
                        }
                        addr += (uint)c._code.Length;
                    }
                }

                List <byte> bytes = new List <byte>();
                foreach (var p in _programm)
                {
                    foreach (var c in p.code)
                    {
                        c.Link();
                        if (c._code.Length > 0)
                        {
                            bytes.AddRange(c._code);
                        }
                    }
                    if (bytes.Count > 0)
                    {
                        HexN[p.code.First().addr] = bytes.ToArray();
                        if (Verbose)
                        {
                            Log.Debug("{0}", p.ToString());
                        }
                    }
                    bytes.Clear();
                }
                Hex         = HexN;
                StackBottom = (uint)((global.memBlocks.Last().start + 7) / 8);
                Log.Info("Used ROM: {0} bytes, RAM: {1} bytes", Hex.Select(z => z.Key + z.Value.Length).Max(), StackBottom);
                success = true;
            }
            catch (JSException ex) {
                var syntaxError = ex.Error.Value as NiL.JS.BaseLibrary.SyntaxError;
                if (syntaxError != null)
                {
                    Log.Error("{0}", syntaxError.message);
                }
                else
                {
                    Log.Error("Compile - {0}: {1}", ex.GetType().Name, ex.Message);
                }
            }
            catch (Exception ex) {
                Log.Error("Compile - {0}: {1}", ex.GetType().Name, ex.Message);
            }
            _scope    = null;
            _programm = null;
            _sp       = null;

            return(success);
        }