diff --git a/radius.rb b/radius.rb index b65b5b4..724bfd8 100644 --- a/radius.rb +++ b/radius.rb @@ -77,151 +77,165 @@ file.close unless file.nil? # begin line-by-line processing output_buf = "" +# most editors will start numbering with line 1 +linenum = 1 source_contents.each_line do |line| - # state machine - resets each line - in_quote = false - in_comment = false - label_done = false - in_label = false - opcode_done = false - in_opcode = false - operand_done = false - in_operand = false - chars_started = false - quote_char = false - x=0 + # we catch any issue that causes radius to fail and just print out the line + # that it failed on. not the best, but *shrug* + begin + + # state machine - resets each line + in_quote = false + in_comment = false + label_done = false + in_label = false + opcode_done = false + in_opcode = false + operand_done = false + in_operand = false + chars_started = false + quote_char = false + x=0 - buf = "" # line buffer, starts empty each line and is appended to output_buf + buf = "" # line buffer, starts empty each line and is appended to output_buf - # begin char-by-char processing - line.each_char.with_index(0) do |c, i| + # begin char-by-char processing + line.each_char.with_index(0) do |c, i| - # starts with whitespace? do an indent - if i == 0 && c.strip.empty? - buf << " "*mnemonic_col_x # optimize? - x+=mnemonic_col_x - label_done = true - next # SHORT CIRCUIT - end - - # are we in a comment? just print the char - if in_comment - # don't print embedded newline :P - if !c.include?("\n") - buf << c - x+=1 - end - next # SHORT CIRCUIT - end - - # are we in a quote? print, but also look for matching end quote - if in_quote - ##print c - buf << c - x+=1 - if c == quote_char # second quotes - in_quote = false - end - next # SHORT CIRCUIT - end - - # not already in comment or quote - if c.strip.empty? - #ignore - if in_label - in_label = false + # starts with whitespace? do an indent + if i == 0 && c.strip.empty? + buf << " "*mnemonic_col_x # optimize? + x+=mnemonic_col_x label_done = true - # do we need to bump out space - if x > mnemonic_col_x-min_space - buf << " "*min_space # optimize? - x+=min_space - else - buf << " "*(mnemonic_col_x-x) # optimize ? - x+=mnemonic_col_x-x - end - elsif in_opcode - in_opcode = false - opcode_done = true - # do we need to bump out space - if x > operand_col_x-min_space - buf << " "*min_space - x+=min_space - else - buf << " "*(operand_col_x-x) - x+=operand_col_x-x - end - elsif in_operand - in_operand = false - operand_done = true - # do we need to bump out space - if x > comment_col_x-min_space - buf << " "*min_space - x+=min_space - else - buf << " "*(comment_col_x-x) - x+=comment_col_x-x - end + next # SHORT CIRCUIT end + # are we in a comment? just print the char + if in_comment + # don't print embedded newline :P + if !c.include?("\n") + buf << c + x+=1 + end + next # SHORT CIRCUIT + end - next - else - chars_started = true - # see if we are starting a quote - if c == '"' || c == "'" - quote_char = c - in_quote = true - buf << c - # see if we are starting a line with a comment - elsif (c == ';' || c == '*') && i == 0 - in_comment = true - buf << c - x+=1 - # found a semi-colon not in an operand (macro!danger) - # (and not in quote or comment) - elsif c == ';' && !in_operand - in_comment = true - buf << " "*(comment_col_x-x) - x+=comment_col_x-x - buf << c - x+=1 - # found asterisk preceded only by whitespace - elsif c == '*' && line[0..i-1].strip.empty? - in_comment = true - buf << c - x+=1 - # real label! - elsif i == 0 - buf << "" - in_label = true - buf << c - x+=1 - # already in label? - elsif in_label - buf << c - x+=1 - # real opcode! - elsif label_done && !opcode_done - in_opcode = true - buf << c - x+=1 - # already in opcode - elsif in_opcode - buf << c - x+=1 - # real operand! - elsif opcode_done && !operand_done - in_operand = true - buf << c - x+=1 - # already in operand - elsif in_operand + # are we in a quote? print, but also look for matching end quote + if in_quote + ##print c buf << c x+=1 + if c == quote_char # second quotes + in_quote = false + end + next # SHORT CIRCUIT + end + + # not already in comment or quote + if c.strip.empty? + #ignore + if in_label + in_label = false + label_done = true + # do we need to bump out space + if x > mnemonic_col_x-min_space + buf << " "*min_space # optimize? + x+=min_space + else + buf << " "*(mnemonic_col_x-x) # optimize ? + x+=mnemonic_col_x-x + end + elsif in_opcode + in_opcode = false + opcode_done = true + # do we need to bump out space + if x > operand_col_x-min_space + buf << " "*min_space + x+=min_space + else + buf << " "*(operand_col_x-x) + x+=operand_col_x-x + end + elsif in_operand + in_operand = false + operand_done = true + # do we need to bump out space + if x > comment_col_x-min_space + buf << " "*min_space + x+=min_space + else + buf << " "*(comment_col_x-x) + x+=comment_col_x-x + end + end + + + next + else + chars_started = true + # see if we are starting a quote + if c == '"' || c == "'" + quote_char = c + in_quote = true + buf << c + # see if we are starting a line with a comment + elsif (c == ';' || c == '*') && i == 0 + in_comment = true + buf << c + x+=1 + # found a semi-colon not in an operand (macro!danger) + # (and not in quote or comment) + elsif c == ';' && !in_operand + in_comment = true + # protect against "negative" spacing + spaces = 1 > (comment_col_x-x) ? 1 : (comment_col_x-x) + buf << " "*spaces + + x+=comment_col_x-x + buf << c + x+=1 + # found asterisk preceded only by whitespace + elsif c == '*' && line[0..i-1].strip.empty? + in_comment = true + buf << c + x+=1 + # real label! + elsif i == 0 + buf << "" + in_label = true + buf << c + x+=1 + # already in label? + elsif in_label + buf << c + x+=1 + # real opcode! + elsif label_done && !opcode_done + in_opcode = true + buf << c + x+=1 + # already in opcode + elsif in_opcode + buf << c + x+=1 + # real operand! + elsif opcode_done && !operand_done + in_operand = true + buf << c + x+=1 + # already in operand + elsif in_operand + buf << c + x+=1 + end end end + rescue Exception => ex + puts "An error of type #{ex.class} happened, message is #{ex.message}" + abort("We failed to parse on line #{linenum}") + end - + linenum+=1 # move line to buffer, stripping trailing spaces output_buf << buf.rstrip << "\n" end