private static void AddDependingSymb(string symbol, string dependingSymb) { Dictionary <string, UnresolvedSymbol> unsolvedSymbs; if (localScope.isLocalScope) { unsolvedSymbs = localScope.unsolvedSymbols; } else { unsolvedSymbs = unsolvedSymbols; } if (unsolvedSymbs.ContainsKey(symbol)) { unsolvedSymbs[symbol].DependingList.Add(dependingSymb); } else { UnresolvedSymbol unsolved = new UnresolvedSymbol(); unsolved.DependingList = new List <string>(); unsolved.DependingList.Add(dependingSymb); unsolved.ExprList = new List <ushort>(); unsolvedSymbs.Add(symbol, unsolved); } }
private static void ConstantHandler(Match lineReg) { string label = lineReg.Groups["label"].Value; string value = lineReg.Groups["value"].Value; ExprResult res = ResolveExpr(value); if (res.undefinedSymbs.Count == 0) { Symbol symb = new Symbol() { Value = res.Result, Type = res.Type }; AddSymbol(label, symb); } else { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.NbrUndefinedSymb = res.undefinedSymbs.Count; unResSymb.DependingList = new List <string>(); unResSymb.Expr = value; unResSymb.ExprList = new List <ushort>(); foreach (string symb in res.undefinedSymbs) { AddDependingSymb(symb, label); } AddUnsolvedSymbol(label, unResSymb); } }
private static void DataByteHandler(string bytesIn) { string[] bytes = bytesIn.Split(','); foreach (string db in bytes) { string data = db.Trim(); if (CPUDef.isString(data)) // handle strings { data = data.Substring(1, data.Length - 2); foreach (char c in data) { fileOutMemory.Add(Convert.ToByte(c)); currentAddr++; } } else { ExprResult res = ResolveExpr(data); if (res.undefinedSymbs.Count == 0) { fileOutMemory.Add((byte)res.Result); } else { fileOutMemory.Add(0); ushort position = (ushort)(currentAddr - originAddr); UnresolvedExpr expr = new UnresolvedExpr { Position = position, Type = SymbolType.BYTE, addrMode = CPUDef.AddrModes.NO, NbrUndefinedSymb = res.undefinedSymbs.Count, Expr = data }; unsolvedExprList.Add(position, expr); foreach (string symb in res.undefinedSymbs) { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.DependingList = new List <string>(); unResSymb.ExprList = new List <ushort>(); unResSymb.ExprList.Add(position); AddUnsolvedSymbol(symb, unResSymb); } } currentAddr++; } } }
public static void ResolveSymbols() { List <string> resolved = new List <string>(); foreach (string symbName in unsolvedSymbols.Keys) { if (!symbolTable.ContainsKey(symbName)) { continue; } UnresolvedSymbol unresSymb = unsolvedSymbols[symbName]; ResolveSymbolDepsAndExprs(unresSymb); resolved.Add(symbName); } foreach (string symbName in resolved) { unsolvedSymbols.Remove(symbName); } }
private static void ResolveSymbol(string label) { Dictionary <string, UnresolvedSymbol> unsolvedSymbs; if (localScope.isLocalScope) { unsolvedSymbs = localScope.unsolvedSymbols; } else { unsolvedSymbs = unsolvedSymbols; } if (!unsolvedSymbs.ContainsKey(label)) { return; } UnresolvedSymbol unresSymb = unsolvedSymbs[label]; ResolveSymbolDepsAndExprs(unresSymb); unsolvedSymbs.Remove(label); }
private static void ResolveSymbolDepsAndExprs(UnresolvedSymbol unresSymb) { Dictionary <string, UnresolvedSymbol> unsolvedSymbs; if (localScope.isLocalScope) { unsolvedSymbs = localScope.unsolvedSymbols; } else { unsolvedSymbs = unsolvedSymbols; } // resolve depending symbols foreach (string dep in unresSymb.DependingList) { UnresolvedSymbol unresDep = unsolvedSymbs[dep]; unresDep.NbrUndefinedSymb--; if (unresDep.NbrUndefinedSymb <= 0) { ExprResult res = ResolveExpr(unresDep.Expr); AddSymbol(dep, new Symbol() { Value = res.Result, Type = res.Type }); } } // resolve expressions foreach (ushort expr in unresSymb.ExprList) { UnresolvedExpr unresExp = unsolvedExprList[expr]; unresExp.NbrUndefinedSymb--; if (unresExp.NbrUndefinedSymb <= 0) { ExprResult res = ResolveExpr(unresExp.Expr, unresExp.addrMode); GenerateExprBytes(unresExp, res); unsolvedExprList.Remove(expr); } } }
private static void AddUnsolvedSymbol(string unsolvedLabel, UnresolvedSymbol unresSymb) { Dictionary <string, UnresolvedSymbol> unsolvedSymbs; if (localScope.isLocalScope) { unsolvedSymbs = localScope.unsolvedSymbols; } else { unsolvedSymbs = unsolvedSymbols; } if (unsolvedSymbs.ContainsKey(unsolvedLabel)) { UnresolvedSymbol unsolved = unsolvedSymbs[unsolvedLabel]; foreach (string dep in unresSymb.DependingList) { if (!unsolved.DependingList.Contains(dep)) { unsolved.DependingList.Add(dep); } } foreach (ushort expr in unresSymb.ExprList) { if (!unsolved.ExprList.Contains(expr)) { unsolved.ExprList.Add(expr); } } if (!string.IsNullOrEmpty(unresSymb.Expr)) { unsolved.Expr = unresSymb.Expr; } unsolvedSymbs[unsolvedLabel] = unsolved; } else { unsolvedSymbs.Add(unsolvedLabel, unresSymb); } }
private static void EndLocalScopeHandler(Match lineReg) { if (!localScope.isLocalScope) { AddError(Errors.NO_LOCAL_SCOPE); return; } foreach (string symb in localScope.unsolvedSymbols.Keys) { if (unsolvedSymbols.ContainsKey(symb)) { UnresolvedSymbol glUnsolvedSymbol = unsolvedSymbols[symb]; UnresolvedSymbol localUnsolvedSymbol = localScope.unsolvedSymbols[symb]; foreach (string dep in localUnsolvedSymbol.DependingList) { if (!glUnsolvedSymbol.DependingList.Contains(dep)) { glUnsolvedSymbol.DependingList.Add(dep); } } foreach (ushort expr in localUnsolvedSymbol.ExprList) { if (!glUnsolvedSymbol.ExprList.Contains(expr)) { glUnsolvedSymbol.ExprList.Add(expr); } } unsolvedSymbols[symb] = glUnsolvedSymbol; } else { UnresolvedSymbol localUnsolvedSymbol = localScope.unsolvedSymbols[symb]; localUnsolvedSymbol.Expr = null; unsolvedSymbols.Add(symb, localUnsolvedSymbol); } } localScope.isLocalScope = false; localScope.symbolTable.Clear(); localScope.unsolvedSymbols.Clear(); }
private static void DataWordHandler(string wordsIn) { string[] words = wordsIn.Split(','); foreach (string dw in words) { string data = dw.Trim(); ExprResult res = ResolveExpr(data); if (res.undefinedSymbs.Count == 0) { fileOutMemory.AddRange(GetWordBytes((ushort)res.Result)); } else { fileOutMemory.AddRange(new byte[2] { 0, 0 }); ushort position = (ushort)(currentAddr - originAddr); UnresolvedExpr expr = new UnresolvedExpr { Position = position, Type = SymbolType.WORD, addrMode = CPUDef.AddrModes.NO, NbrUndefinedSymb = res.undefinedSymbs.Count, Expr = data }; unsolvedExprList.Add(position, expr); foreach (string symb in res.undefinedSymbs) { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.DependingList = new List <string>(); unResSymb.ExprList = new List <ushort>(); unResSymb.ExprList.Add(position); AddUnsolvedSymbol(symb, unResSymb); } } currentAddr += 2; } }
private static void InstructionHandler(Match lineReg) { string opcode = lineReg.Groups["opcode"].Value; string operands = lineReg.Groups["operands"].Value; if (macros.ContainsKey(opcode)) { Match macroReg = Regex.Match($"{opcode} {operands}", CPUDef.macroReg); CallMacroHandler(macroReg); return; } string label = lineReg.Groups["label"].Value; ushort opcodeAddr = currentAddr; opcode = lineReg.Groups["opcode"].Value.ToUpper(); if (!string.IsNullOrWhiteSpace(label)) { Symbol lSymb = new Symbol { Type = SymbolType.WORD, Value = currentAddr }; AddSymbol(label, lSymb); } Byte[] addrModesValues = CPUDef.OPC_TABLE[opcode]; CPUDef.AddrModes addrMode = CPUDef.AddrModes.NO; List <byte> instBytes = new List <byte>(); CPUDef.InstructionInfo instInfo = new CPUDef.InstructionInfo(); bool syntaxError = true; if (string.IsNullOrWhiteSpace(operands)) { syntaxError = false; // 1 byte opcode if (Array.Exists(CPUDef.ACC_OPC, opc => opc.Equals(opcode))) { addrMode = CPUDef.AddrModes.ACC; } else { addrMode = CPUDef.AddrModes.IMP; } instInfo = new CPUDef.InstructionInfo { addrMode = addrMode, nbrBytes = 1 }; instBytes.Add(addrModesValues[(int)addrMode]); } else { string expr = string.Empty; // 2 bytes opcode if (Array.Exists(CPUDef.REL_OPC, opc => opc.Equals(opcode))) { syntaxError = false; expr = operands; instInfo = new CPUDef.InstructionInfo { addrMode = CPUDef.AddrModes.REL, nbrBytes = 2 }; } else { instInfo = CPUDef.GetInstructionInfo(operands); syntaxError = false; expr = instInfo.expr; } if (syntaxError) { AddError(Errors.OPERANDS); } else { addrMode = instInfo.addrMode; ExprResult exprRes = ResolveExpr(expr, addrMode); if (exprRes.undefinedSymbs.Count == 0) { // convert to zero page if symbol is a single byte if (CPUDef.isAbsoluteAddr(addrMode) && exprRes.Type == SymbolType.BYTE) { addrMode = addrMode + 3; instInfo.nbrBytes = 2; } instBytes.Add(addrModesValues[(int)addrMode]); if (instInfo.nbrBytes == 2) { instBytes.Add((byte)exprRes.Result); } else { instBytes.AddRange(GetWordBytes((ushort)exprRes.Result)); } } else { instBytes.Add(addrModesValues[(int)addrMode]); SymbolType typeExpr; if (instInfo.nbrBytes == 2) { instBytes.AddRange(new byte[1] { 0 }); typeExpr = SymbolType.BYTE; } else // 3 bytes instr { instBytes.AddRange(new byte[2] { 0, 0 }); typeExpr = SymbolType.WORD; } ushort position = (ushort)(opcodeAddr - originAddr + 1); UnresolvedExpr exprObj = new UnresolvedExpr { Position = position, Type = typeExpr, addrMode = addrMode, NbrUndefinedSymb = exprRes.undefinedSymbs.Count, Expr = expr }; unsolvedExprList.Add(position, exprObj); foreach (string symb in exprRes.undefinedSymbs) { UnresolvedSymbol unResSymb = new UnresolvedSymbol(); unResSymb.DependingList = new List <string>(); unResSymb.ExprList = new List <ushort>(); unResSymb.ExprList.Add(position); AddUnsolvedSymbol(symb, unResSymb); } } } } if (!syntaxError) { currentAddr += instInfo.nbrBytes; fileOutMemory.AddRange(instBytes.ToArray()); MainConsole.WriteLine($"{opcode} mode {addrMode.ToString()}"); } }