class ZXLib::Basic::Line

Represents a ZX Basic program line.

The original program line without line number, its length and a terminating ENTER character is stored in a body property as a binary string. line_no is a line number.

Attributes

body[RW]
line[RW]
line_no[RW]

Public Class Methods

new(line_no, body) click to toggle source
# File lib/zxlib/basic.rb, line 242
def initialize(line_no, body)
        @line_no = line_no
        @body = body
end
parse_source_line(line_text, last_line_no=0, line_index=0) click to toggle source

Creates a Basic::Line from a provided BASIC program text.

See: Basic.parse_source

# File lib/zxlib/basic.rb, line 268
def parse_source_line(line_text, last_line_no=0, line_index=0)
        offset = 0
        line_no = if m = Tokenizer::Patterns::SPACES_OR_LINE_NO.match(line_text)
                line_text = m.post_match
                offset = m.end 0
                if m[1].nil?
                        last_line_no.succ
                else
                        m[1].to_i.tap do |n|
                                raise SyntaxError, "line number must be less than or equal to 9999, in line: #{line_index}" if n > 9999
                        end
                end
        else
                last_line_no.succ
        end
        if line_no <= last_line_no && !line_no.zero?
                raise SyntaxError, "line numbers must ascending, in line: #{line_index} no: #{line_no} previous: #{last_line_no}"
        end

        body = ''
        parentheses = 0
        tokenizer = Tokenizer.new line_text, line_index, offset

        body << parse_statement(tokenizer)

        while token = tokenizer.next_token
                if token.keyword?
                        if token.keyword_fn?
                                body << token.to_keyword_char
                                if token.keyword?('BIN')
                                        arg = token.extract_binary_number_argument
                                        body << arg << ?\x0E << ZXLib::Math.pack_number(arg.gsub(Tokenizer::Patterns::SPACE_OR_CONTROL,'').to_i(2), true)
                                elsif token.keyword?('THEN')
                                        raise SyntaxError, "unexpected THEN in line: #{line_index} at: #{token.index}" unless parentheses.zero?
                                        body << parse_statement(tokenizer)
                                end
                        else
                                body << token.to_chars
                        end
                elsif token.number?
                        numstr = token.to_chars
                        numpackstr = numstr.gsub(Tokenizer::Patterns::SPACE_OR_CONTROL,'')
                        body << numstr << ?\x0E << case numpackstr[0]
                        when '&'.freeze then numpackstr[1..].to_i(16)
                        when '\\'.freeze then numpackstr[1..].to_i(8)
                        else
                                numpackstr
                        end.to_f.to_z80bin
                elsif token.quote?
                        body << token.to_chars << parse_string_body(tokenizer)
                elsif token.colon?
                        raise SyntaxError, "unexpected colon in line: #{line_index} at: #{token.index}" unless parentheses.zero?
                        body << token.to_chars << parse_statement(tokenizer)
                else
                        if token.parenthesis_open?
                                parentheses += 1
                        elsif token.parenthesis_close?
                                raise SyntaxError, "parenthesis closed too many times in line: #{line_index} at: #{token.index}" if parentheses.zero?
                                parentheses -= 1
                        end
                        body << token.to_chars
                end
        end
        raise SyntaxError, "parentheses not closed in line: #{line_index}" unless parentheses.zero?
        Line.new line_no, body
end

Public Instance Methods

text(escape_keywords:false, ascii_only:false, se:false) click to toggle source

Creates a textual representation of this line except its number. Returns an UTF-8 encoded string.

See: Program#to_source.

# File lib/zxlib/basic.rb, line 251
def text(escape_keywords:false, ascii_only:false, se:false)
        Tokenizer.program_data_to_text(body, escape_keywords, false, ascii_only, se)
end
to_s(**opts) click to toggle source

Creates a textual representation of this line with the line number. Returns an UTF-8 encoded string.

See: Program#to_source.

# File lib/zxlib/basic.rb, line 259
def to_s(**opts)
        "#{line_no.to_s.rjust(4)} #{text(**opts)}"
end