From 164816c44165cfddb8839a5db682a0f16682940b Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Thu, 14 May 2015 20:39:12 +0300 Subject: [PATCH] basic word functionality and conversion from string --- lib/parfait.rb | 11 +++++++++ lib/parfait/word.rb | 60 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/lib/parfait.rb b/lib/parfait.rb index 72eb645d..b0c11269 100644 --- a/lib/parfait.rb +++ b/lib/parfait.rb @@ -48,3 +48,14 @@ class Parfait::List internal_object_length end end + +# Functions to generate parfait objects +String.class_eval do + def to_word + word = Parfait::Word.new( self.length ) + codepoints.each_with_index do |code , index | + word.set_char(index , char) + end + word + end +end diff --git a/lib/parfait/word.rb b/lib/parfait/word.rb index 2730dbfc..cca9bb36 100644 --- a/lib/parfait/word.rb +++ b/lib/parfait/word.rb @@ -8,11 +8,65 @@ module Parfait # Words are constant, maybe like js strings, ruby symbols # Words are short, but may have spaces class Word < Object - def initialize str - @string = str + # initialize with length. For now we try to keep all non-parfait (including String) out + # Virtual provides methods to create Parfait objects from ruby + def initialize length + super + set_length( length , 32 ) end - attr_reader :string + + def set_length(len , fill_char) + return if len < 0 + counter = self.length() + return if len >= counter + internal_object_grow( ( len + 1 ) / 2) + while( counter < len) + set_char( counter , fill_char) + counter = counter + 1 + end + end + + def set_char at , char + raise "char out of range #{char}" if (char < 0) or (char > 65000) + index = range_correct_index(at) + was = internal_object_get(index / 2 ) + if index % 2 + char = (char << 16) + (was & 0xFFFF) + else + char = char + (was & 0xFFFF0000) + end + internal_object_set( index / 2 , char ) + end + + def get_char at + index = range_correct_index(at) + whole = internal_object_get(index / 2 ) + if index % 2 + char = whole >> 16 + else + char = whole & 0xFFFF + end + return char + end + + def range_correct_index at + index = at + index = self.length + at if at < 0 + raise "index out of range #{at}" if index < 0 + return index + end + + def == other + return false if other.length != self.length + len = self.length + while len + return false if self.get_char(len) != other.get_char(len) + len = len - 1 + end + return true + end + def result= value raise "called" class_for(MoveInstruction).new(value , self , :opcode => :mov)