public List<Command> ProcessStatement(string statement, ref int pc, ref MemoryHandler mem, ref Dictionary<string, bool> compilerFlags) { var commands = new List<Command>(); var parts = statement.Split(' '); if (_reservedVarNames.Contains(parts[1])) throw new CompilerException($"Cannot use variable name {parts[1]} as it is reserved by the compiler", -1); mem.Reserve(parts[1]); if (parts.Length > 2) // var a = b { commands.Add(new Command(Operator.ReadCard, mem[parts[1]]) { NoEncode = true }); commands.Add(new Command(Operator.RawValue, int.Parse(parts[3])) { NoEncode = true }); } return commands; }
public List<Command> ProcessStatement(string statement, ref int pc, ref MemoryHandler mem, ref Dictionary<string, bool> compilerFlags) { //Fancy Linq for removing all spaces from the string var processedStatement = statement.Where(c => c != ' ').Aggregate("", (current, c) => current + c); if (processedStatement.Contains('=')) { var commands = new List<Command>(); if (processedStatement.Contains("+=") || processedStatement.Contains("-=")) { var parts = processedStatement.Split(new string[]{ "+=", "-=" }, StringSplitOptions.RemoveEmptyEntries); var resultName = parts[0]; var op = parts[1]; op = mem.MakeConstantIfNeeded(op, ref commands, ref pc); //If adding/subtracting to accumulator, can skip saving old if (resultName != "acc") { if (!compilerFlags["accumulatorIsVolatile"]) commands.Add(new Command(Operator.StoreAccumulator, 98)); commands.Add(new Command(Operator.ClearAccumulator, mem[resultName])); } if (processedStatement.Contains('+')) commands.Add(new Command(Operator.AddToAccumulator, mem[op])); else if (processedStatement.Contains('-')) commands.Add(new Command(Operator.SubtractFromAccumulator, mem[op])); //If adding/subtracting to accumulator, can skip restore and saving if (resultName != "acc") { if (!mem.IsReserved(resultName)) mem.Reserve(resultName); commands.Add(new Command(Operator.StoreAccumulator, mem[resultName])); if (!compilerFlags["accumulatorIsVolatile"]) { commands.Add(new Command(Operator.ClearAccumulator, 98)); } } return Command.LoadToCards(commands, ref pc); } else { //A=B+C var parts = processedStatement.Split('=', '*', '/', '+', '-'); var resultName = parts[0]; var op1 = parts[1]; //operand 1 var op2 = parts[2]; //operand 2 //Dump acc into mem(98) //put op1 in acc //add/sub to acc //Reserve mem for result (maybe) //dump acc to mem() //restore acc op1 = mem.MakeConstantIfNeeded(op1, ref commands, ref pc); op2 = mem.MakeConstantIfNeeded(op2, ref commands, ref pc); //If adding/subtracting to accumulator, can skip saving old //If adding/subtracting to accumulator, can skip saving old if (resultName != "acc") { if (!compilerFlags["accumulatorIsVolatile"]) commands.Add(new Command(Operator.StoreAccumulator, 98)); commands.Add(new Command(Operator.ClearAccumulator, mem[op1])); } if (processedStatement.Contains('+')) commands.Add(new Command(Operator.AddToAccumulator, mem[op2])); else if (processedStatement.Contains('-')) commands.Add(new Command(Operator.SubtractFromAccumulator, mem[op2])); //If adding/subtracting to accumulator, can skip restore and saving if (resultName != "acc") { if (!mem.IsReserved(resultName)) mem.Reserve(resultName); commands.Add(new Command(Operator.StoreAccumulator, mem[resultName])); if (!compilerFlags["accumulatorIsVolatile"]) { commands.Add(new Command(Operator.ClearAccumulator, 98)); } } return Command.LoadToCards(commands, ref pc); } } else { //A++, A-- var add = processedStatement.Contains('+'); var variable = processedStatement.Trim('+', '-'); var commands = new List<Command>(); //Store accumulator to 98 //Load variable //Increment/deincrement //Store variable //restore accumulator //if target is not acc we can skip saving the acc if (variable != "acc") { var memLocation = mem[variable]; commands.Add(new Command(Operator.StoreAccumulator, 98)); if (!compilerFlags["accumulatorIsVolatile"]) commands.Add(new Command(Operator.ClearAccumulator, memLocation)); } commands.Add(new Command(add ? Operator.AddToAccumulator : Operator.SubtractFromAccumulator, 96)); //mem(96) contains variable 'one' if (variable != "acc" && !compilerFlags["accumulatorIsVolatile"]) { commands.Add(new Command(Operator.StoreAccumulator, mem[variable])); if (!compilerFlags["accumulatorIsVolatile"]) commands.Add(new Command(Operator.ClearAccumulator, 98)); } return Command.LoadToCards(commands, ref pc); } }