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); }