interpreter's display is a RplGrOb

This commit is contained in:
Gwenhael Le Moine 2023-07-07 17:52:31 +02:00
parent 3fa79fe97d
commit c763c7bd4b
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
4 changed files with 85 additions and 77 deletions

View file

@ -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

View file

@ -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 )

View file

@ -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

View file

@ -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