Beispiel #1
0
        public Symbol(string name, Package package = null)
        {
            Name = name;
            if (Name[0] == '$')
            {
                IsDynamic = true;
            }
            else if (Name.Length >= 3 && Name[0] == '*' && Name[Name.Length - 1] == '*')
            {
                IsDynamic = true;
            }
            else
            {
                IsDynamic = false;
            }

            PropList = null;
            Package  = package;

            if (package == Runtime.KeywordPackage)
            {
                _value = this;
                Usage  = SymbolUsage.Constant;
            }
            else
            {
                _value = null;
                Usage  = SymbolUsage.None;
            }
        }
Beispiel #2
0
        static bool NeedAllocReg(SymbolUsage usage)
        {
            switch (usage)
            {
            case SymbolUsage.Parameter:
            case SymbolUsage.SelfParameter:
            case SymbolUsage.Variable:
                return(true);
            }

            return(false);
        }
Beispiel #3
0
        public Symbol(string name, Package package = null)
        {
            Name = name;
            if (Name[0] == '$')
            {
                IsDynamic = true;
            }
            else if (Name.Length >= 3 && Name[0] == '*' && Name[Name.Length - 1] == '*')
            {
                IsDynamic = true;
            }
            else {
                IsDynamic = false;
            }

            PropList = null;
            Package = package;

            if (package == Runtime.KeywordPackage)
            {
                _value = this;
                Usage = SymbolUsage.Constant;
            }
            else {
                _value = null;
                Usage = SymbolUsage.None;
            }
        }
Beispiel #4
0
 public AstSymbolRef(AstNode from, SymbolDef def, SymbolUsage usage) : base(from, def.Name)
 {
     Thedef = def;
     def.References.Add(this);
     Usage = usage;
 }
Beispiel #5
0
        public void Link()
        {
            mUnits.Clear();
            mInstructions.Clear();
            mData.Clear();
            mLit.Clear();
            mBss = 0;
            mAllSymbols.Clear();
            mSymbolUsages.Clear();

            //Placeholder for calling main
            //mInstructions.Add(new Instruction(OpCode.NOOPERATION));
            //mInstructions.Add(new Instruction(OpCode.HALT));//After main returns, HALT

            foreach (string file in mInputFiles)
            {
                CompilationUnit unit    = new CompilationUnit();
                bool            success = unit.Open(file);
                if (success)
                {
                    unit.InstructionOffset = mInstructions.Count;
                    unit.DataOffset        = mData.Count;
                    unit.LitOffset         = mLit.Count;

                    foreach (var i in unit.Instructions)
                    {
                        mInstructions.Add(i);
                    }

                    foreach (var b in unit.Data)
                    {
                        mData.Add(b);
                    }

                    foreach (var b in unit.Lit)
                    {
                        mLit.Add(b);
                    }

                    mBss += (int)unit.Header.BssSize;

                    mUnits.Add(unit);
                }
            }

            TotalInstructionCount = mInstructions.Count;
            TotalDataBytes        = mData.Count;
            TotalLitBytes         = mLit.Count;

            //Resolve internal symbols (after this, data and instructions will be modified in the unit)
            foreach (var unit in mUnits)
            {
                unit.ResolveSymbols();
            }

            mInstructions.Clear();
            mData.Clear();
            mLit.Clear();
            foreach (var unit in mUnits)
            {
                foreach (var i in unit.Instructions)
                {
                    mInstructions.Add(i);
                }

                foreach (var b in unit.Data)
                {
                    mData.Add(b);
                }

                foreach (var b in unit.Lit)
                {
                    mLit.Add(b);
                }
            }

            foreach (var unit in mUnits)
            {
                foreach (var s in unit.Symbols)
                {
                    if (s.Flag == Symbol.EnFlag.Export)
                    {
                        if (mAllSymbols.ContainsKey(s.Name))
                        {
                            throw new Exception(string.Format("Symbol '{0}' in {1} is already defined in {2}", s.Name, unit.File, mAllSymbols[s.Name].Value.File));
                        }
                        else
                        {
                            mAllSymbols.Add(s.Name, new KeyValuePair <Symbol, CompilationUnit>(s, unit));
                        }
                    }
                }
            }

            ResolveExternals();

            //save data and lit symbol usage addresses (including internals) here in order for machine to adjust addresses in runtime
            int symbolId = 0;

            foreach (var unit in mUnits)
            {
                foreach (SymbolUsage su in unit.SymbolUsages)
                {
                    //At this stage, symbol name is not important

                    int address = su.Address;
                    switch (su.Section)
                    {
                    case EnSection.Code:
                        address += unit.InstructionOffset;
                        break;

                    case EnSection.Data:
                        address += unit.DataOffset;
                        break;
                    }
                    SymbolUsage newSu = new SymbolUsage((++symbolId).ToString(), su.Section, address);
                    mSymbolUsages.Add(newSu);
                }
            }

            /*
             * Symbol symbolMain = null;
             * foreach (var unit in mUnits)
             * {
             *  symbolMain = unit.GetSymbol("main");
             *  if (null != symbolMain)
             *  {
             *      if (symbolMain.Section == EnSection.Code)
             *      {
             *          mInstructions[0].Operation = OpCode.CALL;
             *          mInstructions[0].Modifier1 = (UInt16)(OpModifier.Immediate | OpModifier.Absolute);
             *          mInstructions[0].Parameter1 = (symbolMain.Address + unit.InstructionOffset) * Instruction.InstructionSize;
             *      }
             *      else
             *      {
             *          throw new Exception("main function not found!");
             *      }
             *      break;
             *  }
             * }
             * if (null == symbolMain)
             * {
             *  throw new Exception("main() could not be found!");
             * }*/
        }
Beispiel #6
0
        public bool Open(string file)
        {
            mSymbols.Clear();
            mSymbolUseList.Clear();
            mInstructions.Clear();
            mData.Clear();
            mLit.Clear();
            UnresolvedSymbols.Clear();

            File = file;

            FileStream   stream = new FileStream(file, FileMode.Open);
            BinaryReader reader = new BinaryReader(stream);

            mHeader.Deserialize(reader);

            if (mHeader.CodeSize > 0)
            {
                int counter = (int)mHeader.CodeSize;

                while (counter > 0)
                {
                    Int32 op     = reader.ReadInt32();
                    Int16 mod1   = reader.ReadInt16();
                    Int16 mod2   = reader.ReadInt16();
                    Int32 param1 = reader.ReadInt32();
                    Int32 param2 = reader.ReadInt32();

                    OpModifier  m1          = (OpModifier)mod1;
                    OpModifier  m2          = (OpModifier)mod2;
                    Instruction instruction = new Instruction((OpCode)op, m1, m2, param1, param2);

                    mInstructions.Add(instruction);

                    counter -= Instruction.InstructionSize;
                }
            }

            mData = reader.ReadBytes((int)mHeader.DataSize).ToList();
            mLit  = reader.ReadBytes((int)mHeader.LitSize).ToList();

            if (mHeader.SymbolDefinitionTableSize > 0)
            {
                int counter = (int)mHeader.SymbolDefinitionTableSize;

                while (counter > 0)
                {
                    Symbol symbol = Symbol.Deserialize(reader);
                    counter -= symbol.CalculateSize();
                    mSymbols.Add(symbol.Name, symbol);
                }
            }

            if (mHeader.SymbolUsageTableSize > 0)
            {
                int counter = (int)mHeader.SymbolUsageTableSize;

                while (counter > 0)
                {
                    SymbolUsage symbolUsage = SymbolUsage.Deserialize(reader);
                    counter -= symbolUsage.CalculateSize();
                    mSymbolUseList.Add(symbolUsage);
                }
            }

            return(true);
        }
Beispiel #7
0
        internal static Symbol Declare(Node declareNode, Scope s, string name, TokenPos pos, SymbolUsage usage)
        {
            var pre = s.FindSymbol(name);

            if (pre != null)
            {
                throw new CompileException(string.Format("{0} redeclared, pre define: {1}", name, pre.DefinePos), pos);
            }

            Symbol sb = new Symbol();

            sb.Name      = name;
            sb.Decl      = declareNode;
            sb.DefinePos = pos;
            sb.Usage     = usage;


            s.Insert(sb);

            if (declareNode != null)
            {
                var ident = declareNode as Ident;

                if (ident == null)
                {
                    return(sb);
                }

                ident.Symbol = sb;
            }

            return(sb);
        }