public static byte[] Tokenize(BASICProgram program, ref CompilerSettings compilerSettings) { var NextLineAddress = compilerSettings.BaseAddress; var output = new List <byte> { (byte)(NextLineAddress & 0x00ff), (byte)((NextLineAddress & 0xff00) >> 8) }; foreach (var line in program.Lines) { var bytes = TokenizeLine(line); NextLineAddress = NextLineAddress + bytes.Count; output.Add((byte)(NextLineAddress & 0x00ff)); output.Add((byte)((NextLineAddress & 0xff00) >> 8)); foreach (var b in bytes) { output.Add(b); } } //Pad end output.Add(0x00); output.Add(0x00); return(output.ToArray()); }
public BASICProgram HandleRemainingTags(List <ProcessedLine> lines) { //Pass 2, parse comments and the rest of our tags. var Labels = new List <Label>(); var basicProgram = new BASICProgram(); foreach (ProcessedLine line in lines) { if (Utils.TrimLead(line.LineText).StartsWith("'")) { //It's a comment. } else { //Handle any replacement macros string result = line.LineText; _replacementMacros.ForEach(macro => { result = macro.Replace(result); }); //Get the PETSCII and byte tags out of the way. result = ParseTags(result); if (Label.IsLabel(result)) { //Accumulate labels //Has this label already been defined? var labelName = Label.GetLabelName(result); var labelLine = basicProgram.Lines.FirstOrDefault(prgLine => prgLine.Labels.Count(q => q.LabelName == labelName) > 0); if (labelLine != null) { //REDEFINED LABEL ERROR! } else { Labels.Add(new Label(result)); } } else { basicProgram.AddLineByText(result, Labels, line.SourceFileLine); Labels = new List <Label>(); } } } if (compilerSettings.Debug) { basicProgram.Dump("pass2.txt"); } return(basicProgram); }
/// <summary> /// Tokenizes an entire BASIC program /// </summary> /// <returns>The tokenize.</returns> /// <param name="program">Program.</param> /// <param name="compilerSettings">Compiler settings.</param> public static byte[] Tokenize(BASICProgram program, ref CompilerSettings compilerSettings) { Output = new List <byte>(); Lines = new List <OptimizedBASICLine>(); NextLineAddress = compilerSettings.BaseAddress; ThisLineAddress = NextLineAddress; //Adding our load address, essentially Output.Add((byte)(NextLineAddress & 0x00ff)); Output.Add((byte)((NextLineAddress & 0xff00) >> 8)); //Process every line in the file to an optimizedBASIC Line. foreach (var line in program.Lines) { CurrentLine = new OptimizedBASICLine() { OriginalLine = line, BaseAddress = ThisLineAddress, LineNumber = line.Line_Number }; //Get tokenized bytes for this line var tokenizedLineBytes = TokenizeLine(line); CurrentLine.Tokenized = tokenizedLineBytes; //Build the line header (pointer to the next line) NextLineAddress = NextLineAddress + tokenizedLineBytes.Count; Output.Add((byte)(NextLineAddress & 0x00ff)); Output.Add((byte)((NextLineAddress & 0xff00) >> 8)); //Now add our tokenized line Output.AddRange(tokenizedLineBytes); Lines.Add(CurrentLine); ThisLineAddress = NextLineAddress; } var serializedLines = JsonConvert.SerializeObject(Lines); File.WriteAllText("test.json", serializedLines); //Pad end with zeroes Output.Add(0x00); Output.Add(0x00); return(Output.ToArray()); }
public bool InjectLineNumbers(ref BASICProgram basicProgram) { //Pass 3, replace labels in basic line text with line # refs var result = true; try { foreach (var line in basicProgram.Lines) { while (Label.ContainsLabel(line.Text)) { //Get our label text var labelString = Label.FirstLabelInText(line.Text); //Find line this label points to var labelLine = basicProgram.Lines.FirstOrDefault(prgLine => prgLine.Labels.Count(q => q.LabelName == Label.GetLabelName(labelString)) > 0); if (labelLine != null) { //REplace label in line text with line # of target line.Text = line.Text.Replace(labelString, labelLine.Line_Number.ToString()); } else { //UNDEFINED LABEL ERROR! Console.WriteLine("Undefined Label: " + labelString + "in " + line.Text); result = false; break; } } } } catch (Exception ex) { Console.WriteLine(ex); result = false; } basicProgram.Dump("pass3.txt"); return(result); }
//Crunch a basic program public BASICProgram Crunch(BASICProgram basicProgram) { BASICProgram crunchedProgram = new BASICProgram(); var buildLine = BASIC_Line.Copy(basicProgram.Lines[0]); var currentLine = new BASIC_Line(); foreach (var line in basicProgram.Lines.Skip(1)) { currentLine = BASIC_Line.Copy(line); var canConcatenate = true; if (compilerSettings.Debug) { Console.WriteLine("buildLine: " + buildLine.Text); Console.WriteLine("currentLine: " + currentLine.Text); } canConcatenate &= buildLine.CanBeAppendedTo(); canConcatenate &= !basicProgram.DoAnyLinesReferTo(line); canConcatenate &= currentLine.Labels.Count <= 0; canConcatenate &= currentLine.Text.Length + buildLine.Text.Length <= 250; if (canConcatenate) { buildLine.Text += ":" + currentLine.Text.Trim().Replace("\t", ""); } else { //Can't tack anything else onto this, so push our old one on the stack and start on the new one. crunchedProgram.Lines.Add(buildLine);//(buildLine.Text, buildLine.Labels, 0); buildLine = currentLine; } } crunchedProgram.Lines.Add(buildLine); //(currentLine.Text, currentLine.Labels, 0); crunchedProgram.Lines.Add(currentLine); //(currentLine.Text, currentLine.Labels, 0); if (compilerSettings.Debug) { crunchedProgram.Dump("crunch.txt"); } return(crunchedProgram); }