public bool AddLineByData(byte[] bytes) { if (bytes.Length < 2) { return(false); } if (bytes[bytes.Length - 1] != 0) { return(false); } BASIC_Line bl = new BASIC_Line(); bl.Line_Number = bytes[0] + (bytes[1] * 256); bl.Line_Data = new byte[bytes.Length - 3]; for (int i = 2; i < bytes.Length - 3; i++) { bl.Line_Data[i - 2] = bytes[i]; } if (Lines.FirstOrDefault(p => p.Line_Number >= bl.Line_Number) == null) { Lines.Add(bl); } else { //Report collision LastError = "Line Number collision or out of order: " + bl.Line_Number.ToString(); return(false); } return(true); }
private static List <byte> TokenizeLine(BASIC_Line line) { //Needs to encode line number and trailing zero after tokenized basic var tokenizedLineBytes = new List <byte>(); //int linenum = GetLineNumber(line); Already done by preproccesor var first = true; //TODO: Get rid of line numbers entirely for our optimized BASIC //Add line number to the beginning of our output tokenizedLineBytes.Add((byte)(line.Line_Number & 0x00ff)); tokenizedLineBytes.Add((byte)((line.Line_Number & 0xff00) >> 8)); //line = StripLineNumber(line); //Splits the line on any : characters it finds var lineSegments = Utils.SplitLine(line.Text); foreach (var lineSegment in lineSegments) { if (!first) { tokenizedLineBytes.Add(PETSCII.CHAR_COLON); } var tokenizedSegmentBytes = TokenizeBlock(lineSegment); tokenizedLineBytes.AddRange(tokenizedSegmentBytes); first = false; } tokenizedLineBytes.Add(0x00); return(tokenizedLineBytes); }
private static List <byte> TokenizeLine(BASIC_Line line) { //Needs to encode line number and trailing zero after tokenized basic var output = new List <byte>(); //int linenum = GetLineNumber(line); Already done by preproccesor var first = true; output.Add((byte)(line.Line_Number & 0x00ff)); output.Add((byte)((line.Line_Number & 0xff00) >> 8)); //placeholder bytes for next line number //line = StripLineNumber(line); var segments = Utils.SplitLine(line.Text); foreach (var segment in segments) { if (!first) { output.Add(0x3A); } var bytes = TokenizeBlock(segment); foreach (var b in bytes) { output.Add(b); } first = false; } output.Add(0x00); return(output); }
public bool Load(string filename) { bool b = false; try { Program = new List <BASIC_Line>(); bool doneflag = false; byte[] filecontents = File.ReadAllBytes(filename); if (filecontents.Length > 2) { // Get Load Address LoadAddress = filecontents[0] + (256 * filecontents[1]); Linebase = 2; if (filecontents.Length > 4) { while (!doneflag) { NextLine = ((filecontents[Linebase] + (filecontents[Linebase + 1] * 256)) - LoadAddress) + 2; if (NextLine <= 0) { doneflag = true; } else { BASIC_Line bl = new BASIC_Line(); bl.Line_Number = filecontents[Linebase + 2] + (filecontents[Linebase + 3] * 256); int ThisLineLen = NextLine - (Linebase + 4); bl.Line_Data = new byte[ThisLineLen]; for (int i = 0; i < ThisLineLen - 1; i++) { bl.Line_Data[i] = filecontents[Linebase + 4 + i]; } Program.Add(bl); Linebase = NextLine; } } b = true; } } } catch (Exception e) { b = false; LastError = e.Message; } return(b); }
public static BASIC_Line Copy(BASIC_Line line) { var returnLine = new BASIC_Line() { Initialized = line.Initialized, Line_Number = line.Line_Number, Text = line.Text, SourceFileLine = line.SourceFileLine, Labels = new List <Label>() }; foreach (var label in line.Labels) { returnLine.Labels.Add(new Label() { ElementType = label.ElementType, LabelName = label.LabelName, Original = label.Original, Processed = label.Processed }); } return(returnLine); }
public string Detokenize(BASIC_Line input) { string s = input.Line_Number.ToString() + " "; bool quotemode = false; for (int i = 0; i < input.Line_Data.Length; i++) { if (quotemode) { //if (input.Line_Data[i] >= 0xc0 && input.Line_Data[i] <= 0xdf) s=s+ (char)(input.Line_Data[i] - 0x60); s = s + PETSCII.Table[input.Line_Data[i]]; //s = s + Encoding.ASCII.GetString(new byte[]{input.Line_Data[i]}); if (input.Line_Data[i] == 0x22) { quotemode = false; } } else { if (input.Line_Data[i] == 0x22) { quotemode = true; s = s + "\""; } else { MicrosoftBasic2Token token = MicrosoftBasic2.Tokens.FirstOrDefault(p => p.Token.Equals(input.Line_Data[i])); if (token != null) { s = s + ((token.LeadingSpace && (s.Substring(s.Length - 1, 1) != " "))?" ":"") + token.ASCII + ((token.TrailingSpace && (i < input.Line_Data.Length && (input.Line_Data[i + 1] != 0x20)))?" ":""); } else { s = s + Encoding.ASCII.GetString(new byte[] { input.Line_Data[i] }); } } } } return(s); }
public bool DoAnyLinesReferTo(BASIC_Line line) { var referenceFound = false; if (line.Line_Number > -1) { referenceFound = (Lines.Count(l => l.RefersToLine(line.Line_Number)) > 0); } if (line.Labels.Count > 0) { foreach (var label in line.Labels) { if (Lines.Count(ln => ln.RefersToLabel(label.LabelName)) > 0) { referenceFound = true; break; } } } return(referenceFound); }
//Add a line by text, either with or without a line number. //If the line does not begin with a line number, it will use the next available. public bool AddLineByText(string line_text, List <Label> labels, int sourceFileLine) { bool b = false; try { BASIC_Line bl = new BASIC_Line(line_text, labels, sourceFileLine); if (bl.Line_Number == -1) { try { bl.Line_Number = Lines.Max(p => p.Line_Number) + 1; } catch (Exception) { bl.Line_Number = 1; } Lines.Add(bl); b = true; } else { var line = Lines.FirstOrDefault(p => p.Line_Number >= bl.Line_Number); if (line == null) { Lines.Add(bl); b = true; } else { //Report Collision LastError = "Line Number collision or out of order: " + bl.Line_Number.ToString(); b = false; } } } catch (Exception) { //Notify? } return(b); }
//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); }