koi-vm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.gitignore +2 -0
  2. data/README.rdoc +47 -0
  3. data/Rakefile +42 -0
  4. data/VERSION +1 -0
  5. data/architecture.rdoc +112 -0
  6. data/examples/blastoff.rb +20 -0
  7. data/examples/hello_world.rb +8 -0
  8. data/koi-vm.gemspec +174 -0
  9. data/lib/.gitkeep +0 -0
  10. data/lib/koi-vm/accessors.rb +63 -0
  11. data/lib/koi-vm/core.rb +48 -0
  12. data/lib/koi-vm/exceptions.rb +8 -0
  13. data/lib/koi-vm/helpers.rb +5 -0
  14. data/lib/koi-vm/opcodes/_opcode_constants.rb +58 -0
  15. data/lib/koi-vm/opcodes/_value_constants.rb +10 -0
  16. data/lib/koi-vm/opcodes/comparative_operations/equal.rb +11 -0
  17. data/lib/koi-vm/opcodes/comparative_operations/greater_than.rb +14 -0
  18. data/lib/koi-vm/opcodes/comparative_operations/less_than.rb +14 -0
  19. data/lib/koi-vm/opcodes/control_operations/exit.rb +10 -0
  20. data/lib/koi-vm/opcodes/control_operations/no_op.rb +9 -0
  21. data/lib/koi-vm/opcodes/flow_control_operations/jump.rb +11 -0
  22. data/lib/koi-vm/opcodes/flow_control_operations/jump_if.rb +16 -0
  23. data/lib/koi-vm/opcodes/flow_control_operations/jump_unless.rb +16 -0
  24. data/lib/koi-vm/opcodes/function_operations/call.rb +13 -0
  25. data/lib/koi-vm/opcodes/function_operations/push_function.rb +15 -0
  26. data/lib/koi-vm/opcodes/function_operations/return.rb +11 -0
  27. data/lib/koi-vm/opcodes/function_operations/tailcall.rb +12 -0
  28. data/lib/koi-vm/opcodes/io_operations/gets.rb +10 -0
  29. data/lib/koi-vm/opcodes/io_operations/print.rb +13 -0
  30. data/lib/koi-vm/opcodes/math_operations/add.rb +14 -0
  31. data/lib/koi-vm/opcodes/math_operations/divide.rb +14 -0
  32. data/lib/koi-vm/opcodes/math_operations/multiply.rb +14 -0
  33. data/lib/koi-vm/opcodes/math_operations/subtract.rb +14 -0
  34. data/lib/koi-vm/opcodes/push_operations/push_bool.rb +12 -0
  35. data/lib/koi-vm/opcodes/push_operations/push_float.rb +12 -0
  36. data/lib/koi-vm/opcodes/push_operations/push_int.rb +12 -0
  37. data/lib/koi-vm/opcodes/push_operations/push_nil.rb +10 -0
  38. data/lib/koi-vm/opcodes/push_operations/push_string.rb +12 -0
  39. data/lib/koi-vm/opcodes/stack_operations/dup.rb +11 -0
  40. data/lib/koi-vm/opcodes/stack_operations/pop.rb +11 -0
  41. data/lib/koi-vm/opcodes/stack_operations/stksize.rb +10 -0
  42. data/lib/koi-vm/opcodes/stack_operations/swap.rb +11 -0
  43. data/lib/koi-vm/opcodes/stack_operations/top.rb +13 -0
  44. data/lib/koi-vm/opcodes/stack_operations/typeof.rb +16 -0
  45. data/lib/koi-vm/opcodes/string_operations/concat.rb +12 -0
  46. data/lib/koi-vm/opcodes/string_operations/strlen.rb +12 -0
  47. data/lib/koi-vm/opcodes/string_operations/to_string.rb +16 -0
  48. data/lib/koi-vm/opcodes/variable_operations/get_global.rb +10 -0
  49. data/lib/koi-vm/opcodes/variable_operations/get_local.rb +10 -0
  50. data/lib/koi-vm/opcodes/variable_operations/set_global.rb +11 -0
  51. data/lib/koi-vm/opcodes/variable_operations/set_local.rb +11 -0
  52. data/lib/koi-vm.rb +10 -0
  53. data/test/.gitkeep +0 -0
  54. data/test/performance/.gitignore +1 -0
  55. data/test/performance/simple_benchmark.rb +87 -0
  56. data/test/setup/test_unit_extensions.rb +21 -0
  57. data/test/test_helper.rb +13 -0
  58. data/test/unit/opcodes/comparative_operations/equal_test.rb +116 -0
  59. data/test/unit/opcodes/comparative_operations/greater_than_test.rb +53 -0
  60. data/test/unit/opcodes/comparative_operations/less_than_test.rb +53 -0
  61. data/test/unit/opcodes/control_operations/exit_test.rb +20 -0
  62. data/test/unit/opcodes/control_operations/no_op_test.rb +17 -0
  63. data/test/unit/opcodes/flow_control_operations/jump_if_test.rb +50 -0
  64. data/test/unit/opcodes/flow_control_operations/jump_test.rb +36 -0
  65. data/test/unit/opcodes/flow_control_operations/jump_unless_test.rb +50 -0
  66. data/test/unit/opcodes/function_operations/call_test.rb +39 -0
  67. data/test/unit/opcodes/function_operations/push_function_test.rb +21 -0
  68. data/test/unit/opcodes/function_operations/return_test.rb +31 -0
  69. data/test/unit/opcodes/function_operations/tailcall_test.rb +41 -0
  70. data/test/unit/opcodes/io_operations/gets_test.rb +38 -0
  71. data/test/unit/opcodes/io_operations/print_test.rb +42 -0
  72. data/test/unit/opcodes/math_operations/add_test.rb +62 -0
  73. data/test/unit/opcodes/math_operations/divide_test.rb +62 -0
  74. data/test/unit/opcodes/math_operations/multiply_test.rb +62 -0
  75. data/test/unit/opcodes/math_operations/subtract_test.rb +62 -0
  76. data/test/unit/opcodes/push_operations/push_bool_test.rb +36 -0
  77. data/test/unit/opcodes/push_operations/push_float_test.rb +27 -0
  78. data/test/unit/opcodes/push_operations/push_int_test.rb +27 -0
  79. data/test/unit/opcodes/push_operations/push_nil_test.rb +16 -0
  80. data/test/unit/opcodes/push_operations/push_string_test.rb +27 -0
  81. data/test/unit/opcodes/stack_operations/dup_test.rb +25 -0
  82. data/test/unit/opcodes/stack_operations/pop_test.rb +28 -0
  83. data/test/unit/opcodes/stack_operations/stksize_test.rb +20 -0
  84. data/test/unit/opcodes/stack_operations/swap_test.rb +36 -0
  85. data/test/unit/opcodes/stack_operations/top_test.rb +45 -0
  86. data/test/unit/opcodes/stack_operations/typeof_test.rb +61 -0
  87. data/test/unit/opcodes/string_operations/concat_test.rb +65 -0
  88. data/test/unit/opcodes/string_operations/strlen_test.rb +44 -0
  89. data/test/unit/opcodes/string_operations/to_string_test.rb +70 -0
  90. data/test/unit/opcodes/variable_operations/get_global_test.rb +18 -0
  91. data/test/unit/opcodes/variable_operations/get_local_test.rb +18 -0
  92. data/test/unit/opcodes/variable_operations/set_global_test.rb +27 -0
  93. data/test/unit/opcodes/variable_operations/set_local_test.rb +27 -0
  94. data/test/unit/vm_initialization_test.rb +86 -0
  95. metadata +200 -0
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ test.txt
2
+ test.html
data/README.rdoc ADDED
@@ -0,0 +1,47 @@
1
+ = KoiVM
2
+
3
+ KoiVM is an extremely simple prototype Virtual Machine written in Ruby. It was created with learning in mind and is written so that it is easy to understand and play with.
4
+
5
+ === Examples
6
+
7
+ The standard 'Hello world!', KoiVM style:
8
+
9
+ require 'koi'
10
+ include KoiVM
11
+
12
+ VM.new.run [
13
+ PUSH_STRING, "Hello World!\n",
14
+ PRINT
15
+ ]
16
+
17
+ #=> Hello world!
18
+
19
+ And an old-school 'Blast off' example:
20
+
21
+ require 'koi'
22
+ include KoiVM
23
+
24
+ VM.new.run [
25
+ PUSH_INT, 11,
26
+ PUSH_INT, 1,
27
+ SUBTRACT,
28
+ DUP,
29
+ TO_STRING,
30
+ PRINT,
31
+ PUSH_STRING, ", ",
32
+ PRINT,
33
+ DUP,
34
+ PUSH_INT, 0,
35
+ EQUAL,
36
+ JUMP_UNLESS, -13,
37
+ PUSH_STRING, "Blast Off!\n",
38
+ PRINT
39
+ ]
40
+
41
+ #=> 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, Blast off!
42
+
43
+ === Author & Credits
44
+
45
+ Author:: {Aaron Gough}[mailto:aaron@aarongough.com]
46
+
47
+ Copyright (c) 2010 {Aaron Gough}[http://thingsaaronmade.com/] ({thingsaaronmade.com}[http://thingsaaronmade.com/]), released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gemspec|
11
+ gemspec.name = "koi-vm"
12
+ gemspec.summary = "A prototype Virtual Machine written in Ruby"
13
+ gemspec.description = "A prototype Virtual Machine written in Ruby. Why would anyone write such a thing? Because it's fun, and it's a great learning tool."
14
+ gemspec.email = "aaron@aarongough.com"
15
+ gemspec.homepage = "https://github.com/aarongough/koi"
16
+ gemspec.authors = ["Aaron Gough"]
17
+ gemspec.rdoc_options << '--line-numbers' << '--inline-source'
18
+ gemspec.extra_rdoc_files = ['README.rdoc', 'MIT-LICENSE']
19
+ end
20
+ rescue LoadError
21
+ puts "Jeweler not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+
25
+ desc 'Test Koi.'
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib/*.rb'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = true
31
+ end
32
+
33
+
34
+ desc 'Generate documentation for Koi.'
35
+ Rake::RDocTask.new(:rdoc) do |rdoc|
36
+ rdoc.rdoc_dir = 'rdoc'
37
+ rdoc.title = 'Koi'
38
+ rdoc.options << '--line-numbers' << '--inline-source'
39
+ rdoc.rdoc_files.include('README.rdoc')
40
+ rdoc.rdoc_files.include('lib/**/*.rb')
41
+ rdoc.rdoc_files.include('app/**/*.rb')
42
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/architecture.rdoc ADDED
@@ -0,0 +1,112 @@
1
+ = Koi Architecture
2
+
3
+ This document is a general overview of the Koi VM architecture. It is used internally as a design document and to keep track of what work still needs to be done.
4
+
5
+ === Datatypes
6
+
7
+ * Integer
8
+ * Float
9
+ * String
10
+ * Array (coming later)
11
+ * Hash (coming later)
12
+
13
+ === Operations
14
+
15
+ * Stack
16
+ PUSH_NIL
17
+ PUSH_BOOL boolean
18
+ PUSH_INT integer
19
+ PUSH_FLOAT float
20
+ PUSH_STRING string
21
+ PUSH_ARRAY array
22
+ PUSH_HASH hash
23
+ x POP
24
+ x SWAP
25
+ x DUP
26
+ x TOP number_of_stack_items
27
+
28
+ * Variables
29
+ x SET_LOCAL index
30
+ x GET_LOCAL index
31
+ x SET_GLOBAL index
32
+ x GET_GLOBAL index
33
+
34
+ * Instruction Pointer
35
+ x ABS_JUMP
36
+ x REL_JUMP destination_offset
37
+ x JUMP_IF destination_offset
38
+ x JUMP_UNLESS destination_offset
39
+
40
+ * Integers / Floats
41
+ x ADD
42
+ x SUBTRACT
43
+ x MULTIPLY
44
+ x DIVIDE
45
+ MODULO
46
+ x INCREMENT
47
+ x DECREMENT
48
+ EQUAL
49
+ NOT_EQUAL
50
+ LESS_THAN
51
+ GREATER_THAN
52
+ EQUAL_LESS_THAN
53
+ EQUAL_GREATER_THAN
54
+
55
+ * Strings
56
+ CONCATENATE
57
+ LENGTH
58
+
59
+ * Arrays
60
+ x ARRAY_NEW
61
+ x ARRAY_GET_INDEX
62
+ x ARRAY_PUT_INDEX
63
+ ARRAY_PUSH
64
+ ARRAY_SIZE
65
+ ARRAY_INCLUDE
66
+ ARRAY_EXPLODE
67
+
68
+ * Hashes
69
+ x HASH_NEW
70
+ x HASH_GET_KEY
71
+ x HASH_PUT_KEY
72
+ HASH_SIZE
73
+ HASH_HAS_KEY
74
+ HASH_EXPLODE
75
+
76
+ * Socket I/O
77
+ NEW_SOCKET_IO
78
+
79
+ * File I/O
80
+ x FILE_OPEN
81
+ x FILE_PUT
82
+ FILE_GET
83
+ FILE_FLUSH
84
+ FILE_CLOSE
85
+
86
+ * Anonymous Functions
87
+ FUNCTION_PUSH
88
+ FUNCTION_END
89
+ FUNCTION_CALL
90
+ FUNCTION_RETURN
91
+
92
+ * Fibers
93
+ x FIBER_ID
94
+ FIBER_LENGTH
95
+ x FIBER_NEW
96
+ x FIBER_DELETE
97
+ FIBER_YIELD
98
+
99
+ * Misc
100
+ TYPE_OF
101
+ x TO_STRING
102
+ x EXIT
103
+
104
+
105
+
106
+ === Exceptions
107
+
108
+ * StackError
109
+ Denotes that an error occurred when accessing items on the stack. The most likely cases are that there were not enough items on the stack for an opcode to work, or that the items were not of the correct type.
110
+
111
+ * OperandError
112
+ Denotes that an error occurred when reading an operand for an opcode. This may be because an operand was not supplied, or because it was not of the correct type.
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'koi.rb'))
2
+
3
+ include KoiVM
4
+
5
+ VM.new.run [
6
+ PUSH_INT, 11,
7
+ PUSH_INT, 1,
8
+ SUBTRACT,
9
+ DUP,
10
+ TO_STRING,
11
+ PRINT,
12
+ PUSH_STRING, ", ",
13
+ PRINT,
14
+ DUP,
15
+ PUSH_INT, 0,
16
+ EQUAL,
17
+ JUMP_UNLESS, -13,
18
+ PUSH_STRING, "Blast Off!\n",
19
+ PRINT
20
+ ]
@@ -0,0 +1,8 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'koi.rb'))
2
+
3
+ include KoiVM
4
+
5
+ VM.new.run [
6
+ PUSH_STRING, "Hello World!\n",
7
+ PRINT
8
+ ]
data/koi-vm.gemspec ADDED
@@ -0,0 +1,174 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{koi-vm}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Aaron Gough"]
12
+ s.date = %q{2010-08-25}
13
+ s.description = %q{A prototype Virtual Machine written in Ruby. Why would anyone write such a thing? Because it's fun, and it's a great learning tool.}
14
+ s.email = %q{aaron@aarongough.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "architecture.rdoc",
24
+ "examples/blastoff.rb",
25
+ "examples/hello_world.rb",
26
+ "koi-vm.gemspec",
27
+ "lib/.gitkeep",
28
+ "lib/koi-vm.rb",
29
+ "lib/koi-vm/accessors.rb",
30
+ "lib/koi-vm/core.rb",
31
+ "lib/koi-vm/exceptions.rb",
32
+ "lib/koi-vm/helpers.rb",
33
+ "lib/koi-vm/opcodes/_opcode_constants.rb",
34
+ "lib/koi-vm/opcodes/_value_constants.rb",
35
+ "lib/koi-vm/opcodes/comparative_operations/equal.rb",
36
+ "lib/koi-vm/opcodes/comparative_operations/greater_than.rb",
37
+ "lib/koi-vm/opcodes/comparative_operations/less_than.rb",
38
+ "lib/koi-vm/opcodes/control_operations/exit.rb",
39
+ "lib/koi-vm/opcodes/control_operations/no_op.rb",
40
+ "lib/koi-vm/opcodes/flow_control_operations/jump.rb",
41
+ "lib/koi-vm/opcodes/flow_control_operations/jump_if.rb",
42
+ "lib/koi-vm/opcodes/flow_control_operations/jump_unless.rb",
43
+ "lib/koi-vm/opcodes/function_operations/call.rb",
44
+ "lib/koi-vm/opcodes/function_operations/push_function.rb",
45
+ "lib/koi-vm/opcodes/function_operations/return.rb",
46
+ "lib/koi-vm/opcodes/function_operations/tailcall.rb",
47
+ "lib/koi-vm/opcodes/io_operations/gets.rb",
48
+ "lib/koi-vm/opcodes/io_operations/print.rb",
49
+ "lib/koi-vm/opcodes/math_operations/add.rb",
50
+ "lib/koi-vm/opcodes/math_operations/divide.rb",
51
+ "lib/koi-vm/opcodes/math_operations/multiply.rb",
52
+ "lib/koi-vm/opcodes/math_operations/subtract.rb",
53
+ "lib/koi-vm/opcodes/push_operations/push_bool.rb",
54
+ "lib/koi-vm/opcodes/push_operations/push_float.rb",
55
+ "lib/koi-vm/opcodes/push_operations/push_int.rb",
56
+ "lib/koi-vm/opcodes/push_operations/push_nil.rb",
57
+ "lib/koi-vm/opcodes/push_operations/push_string.rb",
58
+ "lib/koi-vm/opcodes/stack_operations/dup.rb",
59
+ "lib/koi-vm/opcodes/stack_operations/pop.rb",
60
+ "lib/koi-vm/opcodes/stack_operations/stksize.rb",
61
+ "lib/koi-vm/opcodes/stack_operations/swap.rb",
62
+ "lib/koi-vm/opcodes/stack_operations/top.rb",
63
+ "lib/koi-vm/opcodes/stack_operations/typeof.rb",
64
+ "lib/koi-vm/opcodes/string_operations/concat.rb",
65
+ "lib/koi-vm/opcodes/string_operations/strlen.rb",
66
+ "lib/koi-vm/opcodes/string_operations/to_string.rb",
67
+ "lib/koi-vm/opcodes/variable_operations/get_global.rb",
68
+ "lib/koi-vm/opcodes/variable_operations/get_local.rb",
69
+ "lib/koi-vm/opcodes/variable_operations/set_global.rb",
70
+ "lib/koi-vm/opcodes/variable_operations/set_local.rb",
71
+ "test/.gitkeep",
72
+ "test/performance/.gitignore",
73
+ "test/performance/simple_benchmark.rb",
74
+ "test/setup/test_unit_extensions.rb",
75
+ "test/test_helper.rb",
76
+ "test/unit/opcodes/comparative_operations/equal_test.rb",
77
+ "test/unit/opcodes/comparative_operations/greater_than_test.rb",
78
+ "test/unit/opcodes/comparative_operations/less_than_test.rb",
79
+ "test/unit/opcodes/control_operations/exit_test.rb",
80
+ "test/unit/opcodes/control_operations/no_op_test.rb",
81
+ "test/unit/opcodes/flow_control_operations/jump_if_test.rb",
82
+ "test/unit/opcodes/flow_control_operations/jump_test.rb",
83
+ "test/unit/opcodes/flow_control_operations/jump_unless_test.rb",
84
+ "test/unit/opcodes/function_operations/call_test.rb",
85
+ "test/unit/opcodes/function_operations/push_function_test.rb",
86
+ "test/unit/opcodes/function_operations/return_test.rb",
87
+ "test/unit/opcodes/function_operations/tailcall_test.rb",
88
+ "test/unit/opcodes/io_operations/gets_test.rb",
89
+ "test/unit/opcodes/io_operations/print_test.rb",
90
+ "test/unit/opcodes/math_operations/add_test.rb",
91
+ "test/unit/opcodes/math_operations/divide_test.rb",
92
+ "test/unit/opcodes/math_operations/multiply_test.rb",
93
+ "test/unit/opcodes/math_operations/subtract_test.rb",
94
+ "test/unit/opcodes/push_operations/push_bool_test.rb",
95
+ "test/unit/opcodes/push_operations/push_float_test.rb",
96
+ "test/unit/opcodes/push_operations/push_int_test.rb",
97
+ "test/unit/opcodes/push_operations/push_nil_test.rb",
98
+ "test/unit/opcodes/push_operations/push_string_test.rb",
99
+ "test/unit/opcodes/stack_operations/dup_test.rb",
100
+ "test/unit/opcodes/stack_operations/pop_test.rb",
101
+ "test/unit/opcodes/stack_operations/stksize_test.rb",
102
+ "test/unit/opcodes/stack_operations/swap_test.rb",
103
+ "test/unit/opcodes/stack_operations/top_test.rb",
104
+ "test/unit/opcodes/stack_operations/typeof_test.rb",
105
+ "test/unit/opcodes/string_operations/concat_test.rb",
106
+ "test/unit/opcodes/string_operations/strlen_test.rb",
107
+ "test/unit/opcodes/string_operations/to_string_test.rb",
108
+ "test/unit/opcodes/variable_operations/get_global_test.rb",
109
+ "test/unit/opcodes/variable_operations/get_local_test.rb",
110
+ "test/unit/opcodes/variable_operations/set_global_test.rb",
111
+ "test/unit/opcodes/variable_operations/set_local_test.rb",
112
+ "test/unit/vm_initialization_test.rb"
113
+ ]
114
+ s.homepage = %q{https://github.com/aarongough/koi}
115
+ s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--inline-source"]
116
+ s.require_paths = ["lib"]
117
+ s.rubygems_version = %q{1.3.7}
118
+ s.summary = %q{A prototype Virtual Machine written in Ruby}
119
+ s.test_files = [
120
+ "test/performance/simple_benchmark.rb",
121
+ "test/setup/test_unit_extensions.rb",
122
+ "test/test_helper.rb",
123
+ "test/unit/opcodes/comparative_operations/equal_test.rb",
124
+ "test/unit/opcodes/comparative_operations/greater_than_test.rb",
125
+ "test/unit/opcodes/comparative_operations/less_than_test.rb",
126
+ "test/unit/opcodes/control_operations/exit_test.rb",
127
+ "test/unit/opcodes/control_operations/no_op_test.rb",
128
+ "test/unit/opcodes/flow_control_operations/jump_if_test.rb",
129
+ "test/unit/opcodes/flow_control_operations/jump_test.rb",
130
+ "test/unit/opcodes/flow_control_operations/jump_unless_test.rb",
131
+ "test/unit/opcodes/function_operations/call_test.rb",
132
+ "test/unit/opcodes/function_operations/push_function_test.rb",
133
+ "test/unit/opcodes/function_operations/return_test.rb",
134
+ "test/unit/opcodes/function_operations/tailcall_test.rb",
135
+ "test/unit/opcodes/io_operations/gets_test.rb",
136
+ "test/unit/opcodes/io_operations/print_test.rb",
137
+ "test/unit/opcodes/math_operations/add_test.rb",
138
+ "test/unit/opcodes/math_operations/divide_test.rb",
139
+ "test/unit/opcodes/math_operations/multiply_test.rb",
140
+ "test/unit/opcodes/math_operations/subtract_test.rb",
141
+ "test/unit/opcodes/push_operations/push_bool_test.rb",
142
+ "test/unit/opcodes/push_operations/push_float_test.rb",
143
+ "test/unit/opcodes/push_operations/push_int_test.rb",
144
+ "test/unit/opcodes/push_operations/push_nil_test.rb",
145
+ "test/unit/opcodes/push_operations/push_string_test.rb",
146
+ "test/unit/opcodes/stack_operations/dup_test.rb",
147
+ "test/unit/opcodes/stack_operations/pop_test.rb",
148
+ "test/unit/opcodes/stack_operations/stksize_test.rb",
149
+ "test/unit/opcodes/stack_operations/swap_test.rb",
150
+ "test/unit/opcodes/stack_operations/top_test.rb",
151
+ "test/unit/opcodes/stack_operations/typeof_test.rb",
152
+ "test/unit/opcodes/string_operations/concat_test.rb",
153
+ "test/unit/opcodes/string_operations/strlen_test.rb",
154
+ "test/unit/opcodes/string_operations/to_string_test.rb",
155
+ "test/unit/opcodes/variable_operations/get_global_test.rb",
156
+ "test/unit/opcodes/variable_operations/get_local_test.rb",
157
+ "test/unit/opcodes/variable_operations/set_global_test.rb",
158
+ "test/unit/opcodes/variable_operations/set_local_test.rb",
159
+ "test/unit/vm_initialization_test.rb",
160
+ "examples/blastoff.rb",
161
+ "examples/hello_world.rb"
162
+ ]
163
+
164
+ if s.respond_to? :specification_version then
165
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
166
+ s.specification_version = 3
167
+
168
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
169
+ else
170
+ end
171
+ else
172
+ end
173
+ end
174
+
data/lib/.gitkeep ADDED
File without changes
@@ -0,0 +1,63 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ def data_stack
5
+ return @state[:fiber][:data_stack]
6
+ end
7
+
8
+ def data_stack=(stack)
9
+ @state[:fiber][:data_stack] = stack
10
+ end
11
+
12
+ def return_stack
13
+ return @state[:fiber][:return_stack]
14
+ end
15
+
16
+ def return_stack=(stack)
17
+ @state[:fiber][:return_stack] = stack
18
+ end
19
+
20
+ def instruction_pointer
21
+ return @state[:fiber][:instruction_pointer]
22
+ end
23
+
24
+ def instruction_pointer=(ip)
25
+ @state[:fiber][:instruction_pointer] = ip
26
+ end
27
+
28
+ def opcodes
29
+ return @state[:opcodes]
30
+ end
31
+
32
+ def locals
33
+ return @state[:fiber][:locals][@state[:fiber][:level]]
34
+ end
35
+
36
+ def globals
37
+ return @state[:globals]
38
+ end
39
+
40
+ def increment_scope
41
+ @state[:fiber][:level] += 1
42
+ @state[:fiber][:locals][@state[:fiber][:level]] = @state[:fiber][:locals][@state[:fiber][:level] - 1].dup
43
+ end
44
+
45
+ def decrement_scope
46
+ @state[:fiber][:locals].delete_at(@state[:fiber][:level])
47
+ @state[:fiber][:level] -= 1
48
+ end
49
+
50
+ def reload_scope
51
+ @state[:fiber][:locals][@state[:fiber][:level]] = {}
52
+ end
53
+
54
+ def level
55
+ return @state[:fiber][:level]
56
+ end
57
+
58
+ def level=(level)
59
+ @state[:fiber][:level] = level
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,48 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ @@instruction = []
5
+
6
+ attr_accessor :state, :files
7
+
8
+ def initialize(state = {}, opcodes = [])
9
+ default_state = {
10
+ :opcodes => opcodes,
11
+ :globals => {},
12
+ :fiber => {
13
+ :data_stack => [],
14
+ :return_stack => [],
15
+ :locals => [{}],
16
+ :instruction_pointer => 0,
17
+ :level => 0
18
+ }
19
+ }
20
+ @state = default_state.merge(state)
21
+ @files = {}
22
+ raise ArgumentError, "state[:fibers][x] must be a hash" unless(@state[:fiber].is_a?(Hash))
23
+ raise ArgumentError, "state[:fibers][x][:stack] must be an Array" unless(@state[:fiber][:data_stack].is_a?(Array))
24
+ raise ArgumentError, "state[:fibers][x][:stack] must be an Array" unless(@state[:fiber][:return_stack].is_a?(Array))
25
+ raise ArgumentError, "state[:fibers][x][:instruction_pointer] must be an Integer" unless(@state[:fiber][:instruction_pointer].is_a?(Integer))
26
+ raise ArgumentError, "state[:fibers][x][:level] must be an Integer" unless(@state[:fiber][:level].is_a?(Integer))
27
+ raise ArgumentError, "state[:globals] must be a hash" unless(@state[:globals].is_a?(Hash))
28
+ raise ArgumentError, "state[:opcodes] must be an array" unless(@state[:opcodes].is_a?(Array))
29
+ end
30
+
31
+ def run(opcodes = [])
32
+ @state[:opcodes].concat(opcodes)
33
+ opcode_size = @state[:opcodes].size
34
+ while (@state[:fiber][:instruction_pointer] < opcode_size)
35
+ begin
36
+ break if(@@instruction[@state[:opcodes][@state[:fiber][:instruction_pointer]]].call(self) == true)
37
+ rescue NoMethodError
38
+ @state.delete(:opcodes)
39
+ puts "\n\n" + @state.inspect + "\n\n" unless(defined?($test) && $test == true)
40
+ raise
41
+ end
42
+ end
43
+
44
+ return @state
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,8 @@
1
+ class StackError < RuntimeError
2
+ end
3
+
4
+ class ReturnStackError < RuntimeError
5
+ end
6
+
7
+ class OperandError < RuntimeError
8
+ end
@@ -0,0 +1,5 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ end
5
+ end
@@ -0,0 +1,58 @@
1
+ module KoiVM
2
+ # 0
3
+ PUSH_NIL = 0
4
+ PUSH_BOOL = 1
5
+ PUSH_INT = 2
6
+ PUSH_FLOAT = 3
7
+ PUSH_STRING = 4
8
+
9
+ # 20
10
+ JUMP = 20
11
+ JUMP_IF = 21
12
+ JUMP_UNLESS = 22
13
+
14
+ # 40
15
+ POP = 40
16
+ SWAP = 41
17
+ DUP = 42
18
+ STKSIZE = 43
19
+ TYPEOF = 44
20
+ TOP = 45
21
+
22
+ # 60
23
+ ADD = 60
24
+ SUBTRACT = 61
25
+ MULTIPLY = 62
26
+ DIVIDE = 63
27
+
28
+ # 80
29
+ CONCAT = 80
30
+ STRLEN = 81
31
+ TO_STRING = 82
32
+
33
+ # 100
34
+ EQUAL = 100
35
+ LESS_THAN = 101
36
+ GREATER_THAN = 102
37
+
38
+ # 120
39
+ PRINT = 120
40
+ GETS = 121
41
+
42
+ # 140
43
+ SET_LOCAL = 140
44
+ GET_LOCAL = 141
45
+ SET_GLOBAL = 142
46
+ GET_GLOBAL = 143
47
+
48
+ # 160
49
+ PUSH_FUNCTION = 160
50
+ END_FUNCTION = 161
51
+ CALL = 162
52
+ RETURN = 163
53
+ TAILCALL = 164
54
+
55
+ # 240
56
+ NO_OP = 240
57
+ EXIT = 255
58
+ end
@@ -0,0 +1,10 @@
1
+ module KoiVM
2
+ NIL_ = 0
3
+ BOOL_ = 1
4
+ INTEGER_ = 2
5
+ FLOAT_ = 3
6
+ STRING_ = 4
7
+
8
+
9
+ FUNCTION_ = 16
10
+ end
@@ -0,0 +1,11 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ @@instruction[EQUAL] = Proc.new() do |vm|
5
+ raise StackError, "Expecting at least two items on the data stack" unless(vm.data_stack.length > 1)
6
+ vm.data_stack.push([BOOL_, vm.data_stack.pop == vm.data_stack.pop])
7
+ vm.instruction_pointer = vm.instruction_pointer + 1
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ @@instruction[GREATER_THAN] = Proc.new() do |vm|
5
+ raise StackError, "Expecting at least two items on the data stack" unless(vm.data_stack.length > 1)
6
+ result = [BOOL_, vm.data_stack[-2][1] > vm.data_stack[-1][1]]
7
+ vm.data_stack.pop
8
+ vm.data_stack.pop
9
+ vm.data_stack.push(result)
10
+ vm.instruction_pointer = vm.instruction_pointer + 1
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ @@instruction[LESS_THAN] = Proc.new() do |vm|
5
+ raise StackError, "Expecting at least two items on the data stack" unless(vm.data_stack.length > 1)
6
+ result = [BOOL_, vm.data_stack[-2][1] < vm.data_stack[-1][1]]
7
+ vm.data_stack.pop
8
+ vm.data_stack.pop
9
+ vm.data_stack.push(result)
10
+ vm.instruction_pointer = vm.instruction_pointer + 1
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ @@instruction[EXIT] = Proc.new() do |vm|
5
+ vm.instruction_pointer = vm.instruction_pointer + 1
6
+ true
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module KoiVM
2
+ class VM
3
+
4
+ @@instruction[NO_OP] = Proc.new() do |vm|
5
+ vm.instruction_pointer = vm.instruction_pointer + 1
6
+ end
7
+
8
+ end
9
+ end