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; } }
static bool NeedAllocReg(SymbolUsage usage) { switch (usage) { case SymbolUsage.Parameter: case SymbolUsage.SelfParameter: case SymbolUsage.Variable: return(true); } return(false); }
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; } }
public AstSymbolRef(AstNode from, SymbolDef def, SymbolUsage usage) : base(from, def.Name) { Thedef = def; def.References.Add(this); Usage = usage; }
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!"); * }*/ }
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); }
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); }