interpreter's display is a RplGrOb
This commit is contained in:
parent
3fa79fe97d
commit
c763c7bd4b
4 changed files with 85 additions and 77 deletions
8
bin/rpl
8
bin/rpl
|
@ -71,13 +71,7 @@ class RplRepl
|
|||
end
|
||||
|
||||
def print_display
|
||||
puts @interpreter.framebuffer
|
||||
.to_i
|
||||
.to_s(2)
|
||||
.scan(/.{1,#{@interpreter.display_width}}/)
|
||||
.join("\n")
|
||||
.gsub( '0', '_' )
|
||||
.gsub( '1', '.' )
|
||||
puts @interpreter.display_grob.to_text
|
||||
end
|
||||
|
||||
def print_stack
|
||||
|
|
|
@ -7,60 +7,24 @@ require 'bigdecimal/util'
|
|||
require 'rpl/dictionary'
|
||||
require 'rpl/types'
|
||||
|
||||
class BitArray
|
||||
def initialize
|
||||
@mask = 0
|
||||
end
|
||||
|
||||
def []=(position, value)
|
||||
if value.zero?
|
||||
@mask ^= (1 << position)
|
||||
else
|
||||
@mask |= (1 << position)
|
||||
end
|
||||
end
|
||||
|
||||
def [](position)
|
||||
@mask[position]
|
||||
end
|
||||
|
||||
def to_i
|
||||
@mask.to_i
|
||||
end
|
||||
|
||||
def from_i( value )
|
||||
@mask = value.to_i
|
||||
end
|
||||
end
|
||||
|
||||
class Interpreter
|
||||
include BigMath
|
||||
include Types
|
||||
|
||||
attr_reader :stack,
|
||||
:framebuffer,
|
||||
:display_grob,
|
||||
:dictionary,
|
||||
:version
|
||||
|
||||
attr_accessor :show_display,
|
||||
:display_width,
|
||||
:display_height,
|
||||
:precision
|
||||
attr_accessor :show_display
|
||||
|
||||
def initialize( stack: [], dictionary: Dictionary.new )
|
||||
@dictionary = dictionary
|
||||
@stack = stack
|
||||
|
||||
initialize_framebuffer
|
||||
end
|
||||
|
||||
def initialize_framebuffer
|
||||
@framebuffer = BitArray.new
|
||||
|
||||
@display_width = 131
|
||||
@display_height = 64
|
||||
|
||||
@show_display = false
|
||||
|
||||
@display_grob = RplGrOb.new( 'GROB:131:64:0' )
|
||||
end
|
||||
|
||||
def run!( input )
|
||||
|
|
|
@ -2,38 +2,88 @@
|
|||
|
||||
require 'rpl/parser'
|
||||
|
||||
class BitArray
|
||||
def initialize
|
||||
@mask = 0
|
||||
end
|
||||
|
||||
def []=(position, value)
|
||||
if value.zero?
|
||||
@mask ^= (1 << position)
|
||||
else
|
||||
@mask |= (1 << position)
|
||||
end
|
||||
end
|
||||
|
||||
def [](position)
|
||||
@mask[position]
|
||||
end
|
||||
|
||||
def to_i
|
||||
@mask.to_i
|
||||
end
|
||||
|
||||
def from_i( value )
|
||||
@mask = value.to_i
|
||||
end
|
||||
end
|
||||
|
||||
module Types
|
||||
class RplGrOb
|
||||
attr_reader :width,
|
||||
:height,
|
||||
:bits,
|
||||
:value
|
||||
attr_accessor :width,
|
||||
:height,
|
||||
:bits
|
||||
|
||||
def initialize( value )
|
||||
raise RplTypeError unless self.class.can_parse?( value )
|
||||
def initialize( init )
|
||||
raise RplTypeError unless self.class.can_parse?( init )
|
||||
|
||||
parsed = /^GROB:(?<width>\d+):(?<height>\d+):(?<bits>[0-9a-f]+)$/.match( value )
|
||||
parsed = if init.instance_of?( RplGrOb )
|
||||
init.value
|
||||
else
|
||||
/^GROB:(?<width>\d+):(?<height>\d+):(?<bits>[0-9a-f]+)$/.match( init )
|
||||
end
|
||||
|
||||
@width = parsed[:width].to_i
|
||||
@height = parsed[:height].to_i
|
||||
@bits = parsed[:bits].to_i( 16 )
|
||||
@bits = BitArray.new
|
||||
@bits.from_i( parsed[:bits].to_i( 16 ) )
|
||||
end
|
||||
|
||||
@value = [@width, @height, @bits]
|
||||
def value
|
||||
{ width: @width,
|
||||
height: @height,
|
||||
bits: @bits.to_i.to_s( 16 ) }
|
||||
end
|
||||
|
||||
def to_s
|
||||
"GROB:#{@width}:#{@height}:#{@bits.to_s( 16 )}"
|
||||
"GROB:#{@width}:#{@height}:#{@bits.to_i.to_s( 16 )}"
|
||||
end
|
||||
|
||||
def self.can_parse?( value )
|
||||
value.instance_of?( String ) && value.match?(/^GROB:\d+:\d+:[0-9a-f]+$/)
|
||||
value.instance_of?( RplGrOb ) ||
|
||||
( value.instance_of?( String ) && value.match?(/^GROB:\d+:\d+:[0-9a-f]+$/) )
|
||||
end
|
||||
|
||||
def ==( other )
|
||||
other.class == RplGrOb &&
|
||||
other.width == width &&
|
||||
other.height == height &&
|
||||
other.bits == bits
|
||||
other.width == @width &&
|
||||
other.height == @height &&
|
||||
other.bits.to_i == @bits.to_i
|
||||
end
|
||||
|
||||
def to_text
|
||||
@bits.to_i
|
||||
.to_s(2)
|
||||
.ljust(@width * @height, '0')
|
||||
.slice(0, @width * @height)
|
||||
.scan(/.{1,#{@width}}/)
|
||||
.join("\n")
|
||||
.gsub( '0', '_' )
|
||||
.gsub( '1', '.' )
|
||||
end
|
||||
|
||||
def set_pixel( pos_x, pos_y, value )
|
||||
@bits[ ( pos_y * @height ) + pos_x ] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,17 +52,17 @@ module RplLang
|
|||
@show_display = false
|
||||
end )
|
||||
|
||||
@dictionary.add_word!( ['displaywidth→', 'displaywidth->'],
|
||||
@dictionary.add_word!( ['displaywidth'],
|
||||
category,
|
||||
'( -- i ) put framebuffer\'s width on stack',
|
||||
proc do
|
||||
@stack << RplNumeric.new( @display_width.to_i )
|
||||
@stack << RplNumeric.new( @display_grob.width )
|
||||
end )
|
||||
@dictionary.add_word!( ['displayheight→', 'displayheight->'],
|
||||
@dictionary.add_word!( ['displayheight'],
|
||||
category,
|
||||
'( -- i ) put framebuffer\'s height on stack',
|
||||
proc do
|
||||
@stack << RplNumeric.new( @display_height.to_i )
|
||||
@stack << RplNumeric.new( @display_grob.height )
|
||||
end )
|
||||
|
||||
@dictionary.add_word!( ['→displaywidth', '->displaywidth'],
|
||||
|
@ -71,7 +71,7 @@ module RplLang
|
|||
proc do
|
||||
args = stack_extract( [[RplNumeric]] )
|
||||
|
||||
@display_width = args[0].value.to_i
|
||||
@display_grob.width = args[0].value.to_i
|
||||
end )
|
||||
@dictionary.add_word!( ['→displayheight', '->displayheight'],
|
||||
category,
|
||||
|
@ -79,23 +79,23 @@ module RplLang
|
|||
proc do
|
||||
args = stack_extract( [[RplNumeric]] )
|
||||
|
||||
@display_height = args[0].value.to_i
|
||||
@display_grob.height = args[0].value.to_i
|
||||
end )
|
||||
|
||||
@dictionary.add_word!( ['display→', 'display->'],
|
||||
category,
|
||||
'( -- g ) export framebuffer to GrOb',
|
||||
proc do
|
||||
@stack << RplGrOb.new( "GROB:#{@display_width}:#{@display_height}:#{@framebuffer.to_i.to_s( 16 )}" )
|
||||
@stack << RplGrOb.new( @display_grob )
|
||||
end )
|
||||
# @dictionary.add_word!( ['→display', '->display'],
|
||||
# category,
|
||||
# '( g -- ) import GrOb into framebuffer',
|
||||
# proc do
|
||||
# args = stack_extract( [[RplNumeric]] )
|
||||
@dictionary.add_word!( ['→display', '->display'],
|
||||
category,
|
||||
'( g -- ) import GrOb into framebuffer',
|
||||
proc do
|
||||
args = stack_extract( [[RplGrOb]] )
|
||||
|
||||
# @framebuffer = args[0].value.to_i
|
||||
# end )
|
||||
@display_grob = RplGrOb.new( args[0] )
|
||||
end )
|
||||
|
||||
@dictionary.add_word!( ['pixon'],
|
||||
category,
|
||||
|
@ -106,7 +106,7 @@ module RplLang
|
|||
x = args[1].value.to_i
|
||||
y = args[0].value.to_i
|
||||
|
||||
@framebuffer[ ( y * @display_height ) + x ] = 1
|
||||
@display_grob.set_pixel(x, y, 1)
|
||||
end )
|
||||
@dictionary.add_word!( ['pixoff'],
|
||||
category,
|
||||
|
@ -117,7 +117,7 @@ module RplLang
|
|||
x = args[1].value.to_i
|
||||
y = args[0].value.to_i
|
||||
|
||||
@framebuffer[ ( y * @display_height ) + x ] = 0
|
||||
@display_grob.set_pixel(x, y, 0)
|
||||
end )
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue