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