node-marshal 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,36 +1,36 @@
1
- require_relative '../lib/node-marshal.rb'
2
- require 'test/unit'
3
-
4
- # Test node-marshal obfuscator abilities
5
- class TestObfuscator < Test::Unit::TestCase
6
- def test_sym_replace
7
- # Create the node and find all new symbols
8
- symlog = SymbolsLogger.new
9
- node = NodeMarshal.new(:srcfile, 'lifegame.rb')
10
- our_symbols = symlog.new_symbols.map(&:to_s)
11
- node.to_hash
12
- # Try to exclude symbols used in attr_reader and attr_writer constructions
13
- our_symbols = node.get_safe_symbols(our_symbols)
14
- # Prepare hash table for replacement
15
- reptbl = node.get_aliases_table(our_symbols)
16
- life_game_name = reptbl["LifeGame"]
17
- grid_name = reptbl["Grid"]
18
- make_step_name = reptbl["make_step!"].to_sym
19
- cfg_glider_gun_name = reptbl["cfg_glider_gun!"].to_sym
20
- # Replace symbols
21
- puts "----- Symbols replacement table"
22
- puts reptbl.to_s
23
- puts "-------------------------------"
24
- node.replace_symbols(reptbl)
25
- # Rebuild node, save it to the file and reload it
26
- node = node.rebuild
27
- File.open('life.bin', 'wb') {|fp| fp << node.to_bin};
28
- node.compile.eval
29
- # Execute the node
30
- grid_class = Object.const_get(life_game_name).const_get(grid_name)
31
- g = grid_class.new(25, 80)
32
- g.send(cfg_glider_gun_name)
33
- 75.times {g.send(make_step_name)}
34
- puts g.to_ascii
35
- end
36
- end
1
+ require_relative '../lib/node-marshal.rb'
2
+ require 'test/unit'
3
+
4
+ # Test node-marshal obfuscator abilities
5
+ class TestObfuscator < Test::Unit::TestCase
6
+ def test_sym_replace
7
+ # Create the node and find all new symbols
8
+ symlog = SymbolsLogger.new
9
+ node = NodeMarshal.new(:srcfile, 'lifegame.rb')
10
+ our_symbols = symlog.new_symbols.map(&:to_s)
11
+ node.to_hash
12
+ # Try to exclude symbols used in attr_reader and attr_writer constructions
13
+ our_symbols = node.get_safe_symbols(our_symbols)
14
+ # Prepare hash table for replacement
15
+ reptbl = node.get_aliases_table(our_symbols)
16
+ life_game_name = reptbl["LifeGame"]
17
+ grid_name = reptbl["Grid"]
18
+ make_step_name = reptbl["make_step!"].to_sym
19
+ cfg_glider_gun_name = reptbl["cfg_glider_gun!"].to_sym
20
+ # Replace symbols
21
+ puts "----- Symbols replacement table"
22
+ puts reptbl.to_s
23
+ puts "-------------------------------"
24
+ node.replace_symbols(reptbl)
25
+ # Rebuild node, save it to the file and reload it
26
+ node = node.rebuild
27
+ File.open('life.bin', 'wb') {|fp| fp << node.to_bin};
28
+ node.compile.eval
29
+ # Execute the node
30
+ grid_class = Object.const_get(life_game_name).const_get(grid_name)
31
+ g = grid_class.new(25, 80)
32
+ g.send(cfg_glider_gun_name)
33
+ 75.times {g.send(make_step_name)}
34
+ puts g.to_ascii
35
+ end
36
+ end
@@ -1,52 +1,52 @@
1
- # encoding: UTF-8
2
- require_relative '../lib/node-marshal.rb'
3
- require 'test/unit'
4
-
5
-
6
- # This unit tests Ruby 2.3 &. safe navigation operator
7
- class TestQCALL < Test::Unit::TestCase
8
- def test_qcall
9
- qcall_program = %q{
10
- class Account
11
- def initialize(owner_name, owner_address)
12
- @owner_name = owner_name
13
- @owner_info = (owner_address.nil?) ? nil : OwnerInfo.new(owner_address);
14
- end
15
- def owner_name
16
- @owner_name
17
- end
18
- def owner_info
19
- @owner_info
20
- end
21
- end
22
- class OwnerInfo
23
- def initialize(address)
24
- @address = address
25
- end
26
- def address
27
- @address
28
- end
29
- end
30
- a = Account.new("Owner", "Moscow");
31
- puts "'#{a&.owner_name}'"
32
- puts "'#{a&.owner_info&.address}'"
33
- b = Account.new("Owner", nil);
34
- puts "'#{b&.owner_name}'"
35
- puts "'#{b&.owner_info&.address}'"
36
- [a&.owner_name, a&.owner_info&.address, b&.owner_name, b&.owner_info&.address]
37
- }
38
- ver = RUBY_VERSION
39
- ver = (ver[0] + ver[2] + ver[4]).to_i
40
- if ver >= 230
41
- node = NodeMarshal.new(:srcmemory, qcall_program)
42
- node.show_offsets = true
43
- bindump = node.to_bin
44
- node = NodeMarshal.new(:binmemory, bindump)
45
- res_node = node.compile.eval
46
- res_text = eval(qcall_program)
47
- assert_equal(res_text, res_node)
48
- else
49
- assert_equal(false, true, "Ruby 2.3 or higher is required for &. operator test")
50
- end
51
- end
52
- end
1
+ # encoding: UTF-8
2
+ require_relative '../lib/node-marshal.rb'
3
+ require 'test/unit'
4
+
5
+
6
+ # This unit tests Ruby 2.3 &. safe navigation operator
7
+ class TestQCALL < Test::Unit::TestCase
8
+ def test_qcall
9
+ qcall_program = %q{
10
+ class Account
11
+ def initialize(owner_name, owner_address)
12
+ @owner_name = owner_name
13
+ @owner_info = (owner_address.nil?) ? nil : OwnerInfo.new(owner_address);
14
+ end
15
+ def owner_name
16
+ @owner_name
17
+ end
18
+ def owner_info
19
+ @owner_info
20
+ end
21
+ end
22
+ class OwnerInfo
23
+ def initialize(address)
24
+ @address = address
25
+ end
26
+ def address
27
+ @address
28
+ end
29
+ end
30
+ a = Account.new("Owner", "Moscow");
31
+ puts "'#{a&.owner_name}'"
32
+ puts "'#{a&.owner_info&.address}'"
33
+ b = Account.new("Owner", nil);
34
+ puts "'#{b&.owner_name}'"
35
+ puts "'#{b&.owner_info&.address}'"
36
+ [a&.owner_name, a&.owner_info&.address, b&.owner_name, b&.owner_info&.address]
37
+ }
38
+ ver = RUBY_VERSION
39
+ ver = (ver[0] + ver[2] + ver[4]).to_i
40
+ if ver >= 230
41
+ node = NodeMarshal.new(:srcmemory, qcall_program)
42
+ node.show_offsets = true
43
+ bindump = node.to_bin
44
+ node = NodeMarshal.new(:binmemory, bindump)
45
+ res_node = node.compile.eval
46
+ res_text = eval(qcall_program)
47
+ assert_equal(res_text, res_node)
48
+ else
49
+ assert_equal(false, true, "Ruby 2.3 or higher is required for &. operator test")
50
+ end
51
+ end
52
+ end
@@ -1,79 +1,79 @@
1
- #!/usr/bin/ruby
2
- # Simple TETRIS game for Ruby 1.9.x that uses CURSES library
3
- # (C) 2013 Alexey Voskov
4
- require "curses"
5
- include Curses
6
- # TETRIS figure
7
- class Figure
8
- attr_accessor :mat, :x, :y, :rot
9
- FIGURES = [0x0F00,0x0660,0x0270,0x0170,0x0470,0x0360,0x0C60] # Line, square, T, L, L, Z, Z
10
- def initialize
11
- fig = FIGURES[rand(6).round]
12
- rf = ->bf{Array.new(4) {|y| Array.new(4) {|x| (1 << bf.(x,y)) & fig }}}
13
- @mat = [rf.(->x,y{3-x+y*4}), rf.(->x,y{3-y+(3-x)*4}),
14
- rf.(->x,y{x+(3-y)*4}), rf.(->x,y{y+x*4})]
15
- @x, @y, @rot = 5, 0, 0 # Figure position
16
- end
17
- def each_pos &block
18
- (0..3).each {|y| (0..3).each {|x| block.(y,x) if @mat[@rot][y][x] > 0}}
19
- end
20
- # Test the possibility of move and move if possible
21
- def move!(op, unop, scr)
22
- self.each_pos {|y,x| scr.brick!(y+@y,x+@x,GameField::COL_EMPTY) }
23
- op.(self)
24
- unop.(self) if !(ans = scr.place?self)
25
- self.each_pos {|y,x| scr.brick!(y+@y,x+@x,GameField::COL_BRICK) }
26
- refresh
27
- ans
28
- end
29
- end
30
- # TETRIS game fields
31
- class GameField
32
- WIDTH, HEIGHT, BRICK_WIDTH, COL_EMPTY, COL_WALL, COL_BRICK = 16, 26, 2, 0, 1, 2
33
- def initialize # Initialize and show the game fields
34
- @m = Array.new(HEIGHT+2) {[0,0,1,Array.new(WIDTH-6){0},1,0,0].flatten}
35
- (2..WIDTH-3).each {|i| @m[HEIGHT-1][i] = COL_WALL}
36
- lines!
37
- end
38
- def brick!(y,x,c) # Show the brick on the screen
39
- @m[y][x] = c.to_i
40
- return nil if y-3 <= 0
41
- setpos(y-3,x*BRICK_WIDTH)
42
- addstr([". ", "**", "[]"][c])
43
- end
44
- def place?(fig) # Check if the figure can be placed
45
- fig.each_pos {|y,x| return false if @m[y+fig.y][x+fig.x] > 0}
46
- return true
47
- end
48
- def lines! # Erase full lines from the screen
49
- while (ind = @m[0..HEIGHT-2].index {|s| s[3..WIDTH-4].index(COL_EMPTY) == nil}) != nil
50
- (ind-1).step(0,-1) {|i| @m[i+1] = @m[i]}
51
- @m[0] = @m[HEIGHT+1].dup
52
- end
53
- (0..HEIGHT-1).each {|y| (2..WIDTH-3).each {|x| brick!(y,x,@m[y][x])}} # Update the screen (field + borders)
54
- end
55
- end
56
- # Initialize the console and program data
57
- init_screen; clear; noecho; stdscr.keypad(true)
58
- fig, scr, speed = Figure.new, GameField.new, 1
59
- # Keyboard control thread
60
- keythread = Thread.new { loop {
61
- case getch
62
- when Key::LEFT then fig.move!(->f{f.x -=1}, ->f{f.x +=1}, scr)
63
- when Key::RIGHT then fig.move!(->f{f.x +=1}, ->f{f.x -=1}, scr)
64
- when Key::UP then fig.move!(->f{f.rot = (f.rot+1)%4}, ->f{f.rot = (f.rot+3)%4},scr)
65
- when Key::DOWN then speed = 0.05 # Delay for fast falling
66
- end
67
- }}
68
- # Game main loop (new figure creation + falling)
69
- begin
70
- fig, speed = Figure.new, 0.5 # Figure and delay for its normal falling
71
- sleep(speed) while fig.move!(->f{f.y +=1}, ->f{f.y -=1}, scr)
72
- scr.lines!
73
- end until fig.y == 0
74
- # Finish the game
75
- keythread.kill
76
- setpos(GameField::HEIGHT/2,GameField::WIDTH-4)
77
- addstr("GAME OVER!")
78
- getch
79
- close_screen
1
+ #!/usr/bin/ruby
2
+ # Simple TETRIS game for Ruby 1.9.x that uses CURSES library
3
+ # (C) 2013 Alexey Voskov
4
+ require "curses"
5
+ include Curses
6
+ # TETRIS figure
7
+ class Figure
8
+ attr_accessor :mat, :x, :y, :rot
9
+ FIGURES = [0x0F00,0x0660,0x0270,0x0170,0x0470,0x0360,0x0C60] # Line, square, T, L, L, Z, Z
10
+ def initialize
11
+ fig = FIGURES[rand(6).round]
12
+ rf = ->bf{Array.new(4) {|y| Array.new(4) {|x| (1 << bf.(x,y)) & fig }}}
13
+ @mat = [rf.(->x,y{3-x+y*4}), rf.(->x,y{3-y+(3-x)*4}),
14
+ rf.(->x,y{x+(3-y)*4}), rf.(->x,y{y+x*4})]
15
+ @x, @y, @rot = 5, 0, 0 # Figure position
16
+ end
17
+ def each_pos &block
18
+ (0..3).each {|y| (0..3).each {|x| block.(y,x) if @mat[@rot][y][x] > 0}}
19
+ end
20
+ # Test the possibility of move and move if possible
21
+ def move!(op, unop, scr)
22
+ self.each_pos {|y,x| scr.brick!(y+@y,x+@x,GameField::COL_EMPTY) }
23
+ op.(self)
24
+ unop.(self) if !(ans = scr.place?self)
25
+ self.each_pos {|y,x| scr.brick!(y+@y,x+@x,GameField::COL_BRICK) }
26
+ refresh
27
+ ans
28
+ end
29
+ end
30
+ # TETRIS game fields
31
+ class GameField
32
+ WIDTH, HEIGHT, BRICK_WIDTH, COL_EMPTY, COL_WALL, COL_BRICK = 16, 26, 2, 0, 1, 2
33
+ def initialize # Initialize and show the game fields
34
+ @m = Array.new(HEIGHT+2) {[0,0,1,Array.new(WIDTH-6){0},1,0,0].flatten}
35
+ (2..WIDTH-3).each {|i| @m[HEIGHT-1][i] = COL_WALL}
36
+ lines!
37
+ end
38
+ def brick!(y,x,c) # Show the brick on the screen
39
+ @m[y][x] = c.to_i
40
+ return nil if y-3 <= 0
41
+ setpos(y-3,x*BRICK_WIDTH)
42
+ addstr([". ", "**", "[]"][c])
43
+ end
44
+ def place?(fig) # Check if the figure can be placed
45
+ fig.each_pos {|y,x| return false if @m[y+fig.y][x+fig.x] > 0}
46
+ return true
47
+ end
48
+ def lines! # Erase full lines from the screen
49
+ while (ind = @m[0..HEIGHT-2].index {|s| s[3..WIDTH-4].index(COL_EMPTY) == nil}) != nil
50
+ (ind-1).step(0,-1) {|i| @m[i+1] = @m[i]}
51
+ @m[0] = @m[HEIGHT+1].dup
52
+ end
53
+ (0..HEIGHT-1).each {|y| (2..WIDTH-3).each {|x| brick!(y,x,@m[y][x])}} # Update the screen (field + borders)
54
+ end
55
+ end
56
+ # Initialize the console and program data
57
+ init_screen; clear; noecho; stdscr.keypad(true)
58
+ fig, scr, speed = Figure.new, GameField.new, 1
59
+ # Keyboard control thread
60
+ keythread = Thread.new { loop {
61
+ case getch
62
+ when Key::LEFT then fig.move!(->f{f.x -=1}, ->f{f.x +=1}, scr)
63
+ when Key::RIGHT then fig.move!(->f{f.x +=1}, ->f{f.x -=1}, scr)
64
+ when Key::UP then fig.move!(->f{f.rot = (f.rot+1)%4}, ->f{f.rot = (f.rot+3)%4},scr)
65
+ when Key::DOWN then speed = 0.05 # Delay for fast falling
66
+ end
67
+ }}
68
+ # Game main loop (new figure creation + falling)
69
+ begin
70
+ fig, speed = Figure.new, 0.5 # Figure and delay for its normal falling
71
+ sleep(speed) while fig.move!(->f{f.y +=1}, ->f{f.y -=1}, scr)
72
+ scr.lines!
73
+ end until fig.y == 0
74
+ # Finish the game
75
+ keythread.kill
76
+ setpos(GameField::HEIGHT/2,GameField::WIDTH-4)
77
+ addstr("GAME OVER!")
78
+ getch
79
+ close_screen
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: node-marshal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Voskov
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir:
10
10
  - bin
11
11
  cert_chain: []
12
- date: 2016-03-16 00:00:00.000000000 Z
12
+ date: 2017-05-01 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: "This gem is designed for transformation of Ruby source code (eiher in
15
15
  the form of files or strings) to the \nRuby nodes (syntax trees) used by Ruby MRI
@@ -43,6 +43,7 @@ files:
43
43
  - test/test_base.rb
44
44
  - test/test_complex.rb
45
45
  - test/test_lifegame.rb
46
+ - test/test_namedarg.rb
46
47
  - test/test_obfuscator.rb
47
48
  - test/test_qcall.rb
48
49
  - test/tinytet.rb
@@ -68,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
69
  version: '0'
69
70
  requirements: []
70
71
  rubyforge_project:
71
- rubygems_version: 2.5.1
72
+ rubygems_version: 2.5.2
72
73
  signing_key:
73
74
  specification_version: 4
74
75
  summary: Transforms Ruby sources to binary nodes (trees) that can be saved and loaded