示例#1
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        //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);
        }
示例#9
0
        //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);
        }