public static int ParseParameter(Command.ParameterType t, PreParsedLine l, out ParsedType foundType, Dictionary <string, Alias> aliases, Dictionary <string, int> labels = null) { int x = 0; foundType = ParsedType.Constant; switch (t) { case Command.ParameterType.Label: if (labels != null && !labels.TryGetValue(l.Parameter.Value, out x)) { throw new ArgumentException("Unable to find label '" + l.Parameter + "' of line '" + l.InputLine + "'"); } foundType = ParsedType.Label; break; case Command.ParameterType.Constant: if (!int.TryParse(l.Parameter.Value, out x)) { throw new ArgumentException("Unable to parse parameter '" + l.Parameter + "' of line '" + l.InputLine + "'"); } break; case Command.ParameterType.StackDelta: x = ParseNonNegative(l); foundType = ParsedType.StackDelta; break; case Command.ParameterType.StackAddress: x = ParseNonNegative(l); foundType = ParsedType.Address; break; case Command.ParameterType.Address: foundType = ParsedType.Address; if (!int.TryParse(l.Parameter.Value, out x)) { Alias alias; if (aliases.TryGetValue(l.Parameter.Value, out alias)) { x = alias.Address; foundType = ParsedType.Alias; } else { throw new ArgumentException("Unable to parse address parameter '" + l.Parameter + "' of line '" + l.InputLine + "'. Parameter is no valid integer, or known alias"); } } if (x < 0 || x >= State.MemorySize) { throw new ArgumentException("Address parameter '" + l.Parameter + "' of line '" + l.InputLine + "' exceeds valid address range"); } break; } return(x); }
private static int ParseNonNegative(PreParsedLine l) { int x = 0; if (!int.TryParse(l.Parameter.Value, out x)) { throw new ArgumentException("Unable to parse parameter '" + l.Parameter + "' of line '" + l.InputLine + "'"); } if (x < 0) { throw new ArgumentException("Parameter '" + l.Parameter + "' of line '" + l.InputLine + "' must not be negative"); } if (x >= State.MemorySize) { throw new ArgumentException("Parameter '" + l.Parameter + "' of line '" + l.InputLine + "' must be less than the address space size " + State.MemorySize); } return(x); }
public static Instruction[] Parse(IEnumerable <string> lines) { int lineIndex = 0; var labels = new Dictionary <string, int>(); var instructions = new List <Instruction>(); lineIndex = 0; int commandCounter = 0; Dictionary <string, Alias> aliases = new Dictionary <string, Alias>(); foreach (var line in lines) { lineIndex++; try { var l = new PreParsedLine(line); if (l.Label.HasValue) { if (labels.ContainsKey(l.Label.Value)) { throw new ArgumentException("Label '" + l.Label.Value + "' re-defined. Was originally defined at command #" + labels[l.Label.Value]); } labels.Add(l.Label.Value, commandCounter); } if (l.IsAlias) { var alias = l.ToAlias(); if (aliases.ContainsKey(alias.Name)) { throw new ArgumentException("Alias '" + alias.Name + "' already defined"); } aliases.Add(alias.Name, alias); if (l.IntAliasValue.HasValue) { commandCounter++; //set } } if (l.IsCommand) { commandCounter++; } } catch (Exception ex) { throw new CommandException(ex, line, lineIndex); } } foreach (var alias in aliases.Values) { if (alias.InitialValue.HasValue) { instructions.Add(new Instruction(s => { s.m[alias.Address] = alias.InitialValue.Value; s.LogM(alias.Address); }, alias.ToString())); } } lineIndex = 0; foreach (var line in lines) { lineIndex++; var l = new PreParsedLine(line); if (!l.IsCommand) { continue; } Action <State> action = null; string lineText = ""; Language.Command command; try { command = Language.FindCommand(l.Command.Value, l.Parameter != null); } catch (Exception ex) { throw new CommandException(ex, line, lineIndex); } if (l.Label != null) { lineText = l.Label + "(=" + instructions.Count + "): "; } else { lineText = "(" + instructions.Count + "): "; } if (command.RequiresParameter) { ParsedType ignore; int x = ParseParameter(command.Parameter, l, out ignore, aliases, labels); action = (s) => command.Action(s, x); lineText += command.Name + " " + "" + l.Parameter; } else { action = (s) => command.Action(s, 0); lineText += command.Name; } instructions.Add(new Instruction(action, lineText)); } return(instructions.ToArray()); }