koi-reference-compiler 0.0.1

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.
Files changed (79) hide show
  1. data/.gitignore +3 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +76 -0
  4. data/Rakefile +42 -0
  5. data/VERSION +1 -0
  6. data/lib/koi-reference-compiler.rb +10 -0
  7. data/lib/koi-reference-compiler/exceptions.rb +2 -0
  8. data/lib/koi-reference-compiler/koi-reference-compiler.rb +23 -0
  9. data/lib/koi-reference-compiler/node_extensions/assignment/assignment.rb +12 -0
  10. data/lib/koi-reference-compiler/node_extensions/blocks/block.rb +13 -0
  11. data/lib/koi-reference-compiler/node_extensions/control_flow/if.rb +14 -0
  12. data/lib/koi-reference-compiler/node_extensions/control_flow/unless.rb +14 -0
  13. data/lib/koi-reference-compiler/node_extensions/expressions/additive_expression.rb +13 -0
  14. data/lib/koi-reference-compiler/node_extensions/expressions/comparative_expression.rb +13 -0
  15. data/lib/koi-reference-compiler/node_extensions/expressions/expression.rb +9 -0
  16. data/lib/koi-reference-compiler/node_extensions/expressions/multitive_expression.rb +13 -0
  17. data/lib/koi-reference-compiler/node_extensions/functions/function_call.rb +54 -0
  18. data/lib/koi-reference-compiler/node_extensions/functions/function_definition.rb +19 -0
  19. data/lib/koi-reference-compiler/node_extensions/hash_literals/hash_access.rb +12 -0
  20. data/lib/koi-reference-compiler/node_extensions/hash_literals/hash_accessor.rb +15 -0
  21. data/lib/koi-reference-compiler/node_extensions/hash_literals/hash_accessor_list.rb +26 -0
  22. data/lib/koi-reference-compiler/node_extensions/hash_literals/hash_assignment.rb +17 -0
  23. data/lib/koi-reference-compiler/node_extensions/hash_literals/hash_literal.rb +11 -0
  24. data/lib/koi-reference-compiler/node_extensions/hash_literals/key_value.rb +13 -0
  25. data/lib/koi-reference-compiler/node_extensions/hash_literals/key_value_list.rb +13 -0
  26. data/lib/koi-reference-compiler/node_extensions/identifiers/identifier.rb +31 -0
  27. data/lib/koi-reference-compiler/node_extensions/literals/false_literal.rb +9 -0
  28. data/lib/koi-reference-compiler/node_extensions/literals/float_literal.rb +9 -0
  29. data/lib/koi-reference-compiler/node_extensions/literals/integer_literal.rb +9 -0
  30. data/lib/koi-reference-compiler/node_extensions/literals/nil_literal.rb +9 -0
  31. data/lib/koi-reference-compiler/node_extensions/literals/string_literal.rb +9 -0
  32. data/lib/koi-reference-compiler/node_extensions/literals/true_literal.rb +9 -0
  33. data/lib/koi-reference-compiler/node_extensions/operators/addition_operator.rb +9 -0
  34. data/lib/koi-reference-compiler/node_extensions/operators/assignment_operator.rb +6 -0
  35. data/lib/koi-reference-compiler/node_extensions/operators/division_operator.rb +9 -0
  36. data/lib/koi-reference-compiler/node_extensions/operators/equality_operator.rb +9 -0
  37. data/lib/koi-reference-compiler/node_extensions/operators/great_than_operator.rb +9 -0
  38. data/lib/koi-reference-compiler/node_extensions/operators/inequality_operator.rb +9 -0
  39. data/lib/koi-reference-compiler/node_extensions/operators/less_than_operator.rb +9 -0
  40. data/lib/koi-reference-compiler/node_extensions/operators/multiplication_operator.rb +9 -0
  41. data/lib/koi-reference-compiler/node_extensions/operators/subtraction_operator.rb +9 -0
  42. data/lib/koi-reference-compiler/node_extensions/statements/statement.rb +9 -0
  43. data/lib/koi-reference-compiler/syntax_node.rb +18 -0
  44. data/lib/koi-reference-compiler/vm_opcodes.rb +70 -0
  45. data/test/compiler/unit/ast_hash_loader/ast_hash_loader_test.rb +46 -0
  46. data/test/compiler/unit/node_extensions/assignment/assignment_test.rb +22 -0
  47. data/test/compiler/unit/node_extensions/blocks/block_test.rb +37 -0
  48. data/test/compiler/unit/node_extensions/control_flow/if_test.rb +39 -0
  49. data/test/compiler/unit/node_extensions/control_flow/unless_test.rb +40 -0
  50. data/test/compiler/unit/node_extensions/expressions/additive_expression_test.rb +21 -0
  51. data/test/compiler/unit/node_extensions/expressions/comparative_expression_test.rb +21 -0
  52. data/test/compiler/unit/node_extensions/expressions/expression_test.rb +17 -0
  53. data/test/compiler/unit/node_extensions/expressions/multitive_expression_test.rb +21 -0
  54. data/test/compiler/unit/node_extensions/functions/function_call_test.rb +296 -0
  55. data/test/compiler/unit/node_extensions/functions/function_definition_test.rb +37 -0
  56. data/test/compiler/unit/node_extensions/hash_literals/hash_accessor_list_test.rb +83 -0
  57. data/test/compiler/unit/node_extensions/hash_literals/hash_accessor_test.rb +33 -0
  58. data/test/compiler/unit/node_extensions/hash_literals/hash_literal_test.rb +29 -0
  59. data/test/compiler/unit/node_extensions/hash_literals/key_value_list_test.rb +37 -0
  60. data/test/compiler/unit/node_extensions/hash_literals/key_value_test.rb +24 -0
  61. data/test/compiler/unit/node_extensions/identifiers/identifier_test.rb +103 -0
  62. data/test/compiler/unit/node_extensions/literals/false_literal_test.rb +13 -0
  63. data/test/compiler/unit/node_extensions/literals/float_literal_test.rb +13 -0
  64. data/test/compiler/unit/node_extensions/literals/integer_literal_test.rb +13 -0
  65. data/test/compiler/unit/node_extensions/literals/nil_literal_test.rb +13 -0
  66. data/test/compiler/unit/node_extensions/literals/string_literal_test.rb +13 -0
  67. data/test/compiler/unit/node_extensions/literals/true_literal_test.rb +13 -0
  68. data/test/compiler/unit/node_extensions/operators/addition_operator_test.rb +13 -0
  69. data/test/compiler/unit/node_extensions/operators/division_operator_test.rb +13 -0
  70. data/test/compiler/unit/node_extensions/operators/equality_operator_test.rb +13 -0
  71. data/test/compiler/unit/node_extensions/operators/greater_than_operator_test.rb +13 -0
  72. data/test/compiler/unit/node_extensions/operators/inequality_operator_test.rb +13 -0
  73. data/test/compiler/unit/node_extensions/operators/less_than_operator_test.rb +13 -0
  74. data/test/compiler/unit/node_extensions/operators/multiplication_operator_test.rb +13 -0
  75. data/test/compiler/unit/node_extensions/operators/subtraction_operator_test.rb +13 -0
  76. data/test/compiler/unit/node_extensions/statements/statement_test.rb +24 -0
  77. data/test/setup/test_unit_extensions.rb +21 -0
  78. data/test/test_helper.rb +10 -0
  79. metadata +177 -0
@@ -0,0 +1,17 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class HashAssignment < SyntaxNode
4
+ def compile
5
+ expression = self.elements[3].compile
6
+
7
+ bytecode = []
8
+ bytecode.concat( self.elements[0].compile )
9
+ bytecode.concat( self.elements[1].compile )
10
+ tmp = bytecode.slice!(-2,2)
11
+ bytecode.concat( expression )
12
+ bytecode.concat( tmp )
13
+ return bytecode
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,11 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class HashLiteral < SyntaxNode
4
+ def compile
5
+ bytecode = [PUSH_HASH]
6
+ bytecode.concat( self.elements.first.compile )
7
+ return bytecode
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,13 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class KeyValue < SyntaxNode
4
+ def compile
5
+ bytecode = []
6
+ bytecode.concat(self.elements[0].compile)
7
+ bytecode.concat(self.elements[1].compile)
8
+ bytecode << SET_KEY
9
+ return bytecode
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class KeyValueList < SyntaxNode
4
+ def compile
5
+ bytecode = []
6
+ self.elements.each do |element|
7
+ bytecode.concat(element.compile)
8
+ end
9
+ return bytecode
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,31 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class Identifier < SyntaxNode
4
+ def compile
5
+ identifier = self.text_value
6
+ parent = self.parent
7
+ if(identifier[0] == "$")
8
+ if(parent.is_a?(Expression) || parent.is_a?(MultitiveExpression) || parent.is_a?(AdditiveExpression) || parent.is_a?(ComparativeExpression) || parent.is_a?(HashAssignment) || parent.is_a?(HashAccess))
9
+ [ GET_GLOBAL, identifier.to_sym ]
10
+
11
+ elsif(parent.is_a?(Assignment) || parent.is_a?(FunctionDefinition))
12
+ [ SET_GLOBAL, identifier.to_sym ]
13
+
14
+ else
15
+ raise CompileError, "Unkown parent for Identfier: #{self.parent.class}"
16
+ end
17
+ else
18
+ if(parent.is_a?(Expression) || parent.is_a?(MultitiveExpression) || parent.is_a?(AdditiveExpression) || parent.is_a?(ComparativeExpression) || parent.is_a?(HashAssignment) || parent.is_a?(HashAccess))
19
+ [ GET_LOCAL, identifier.to_sym ]
20
+
21
+ elsif(parent.is_a?(Assignment) || parent.is_a?(FunctionDefinition))
22
+ [ SET_LOCAL, identifier.to_sym ]
23
+
24
+ else
25
+ raise CompileError, "Unkown parent for Identfier: #{self.parent.class}"
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class FalseLiteral < SyntaxNode
4
+ def compile
5
+ [ PUSH_BOOL, false ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class FloatLiteral < SyntaxNode
4
+ def compile
5
+ [ PUSH_FLOAT, self.text_value.to_f ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class IntegerLiteral < SyntaxNode
4
+ def compile
5
+ [ PUSH_INT, self.text_value.to_i ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class NilLiteral < SyntaxNode
4
+ def compile
5
+ [ PUSH_NIL ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class StringLiteral < SyntaxNode
4
+ def compile
5
+ [ PUSH_STRING, self.text_value.slice(1, self.text_value.length - 2) ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class TrueLiteral < SyntaxNode
4
+ def compile
5
+ [ PUSH_BOOL, true ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class AdditionOperator < SyntaxNode
4
+ def compile
5
+ [ ADD ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,6 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class AssignmentOperator < SyntaxNode
4
+ end
5
+
6
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class DivisionOperator < SyntaxNode
4
+ def compile
5
+ [ DIVIDE ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class EqualityOperator < SyntaxNode
4
+ def compile
5
+ [ EQUAL ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class GreaterThanOperator < SyntaxNode
4
+ def compile
5
+ [ GREATER_THAN ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class InequalityOperator < SyntaxNode
4
+ def compile
5
+ [ EQUAL, INVERT ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class LessThanOperator < SyntaxNode
4
+ def compile
5
+ [ LESS_THAN ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class MultiplicationOperator < SyntaxNode
4
+ def compile
5
+ [ MULTIPLY ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class SubtractionOperator < SyntaxNode
4
+ def compile
5
+ [ SUBTRACT ]
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class Statement < SyntaxNode
4
+ def compile
5
+ return self.elements.first.compile
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,18 @@
1
+ module KoiReferenceCompiler
2
+
3
+ class SyntaxNode
4
+
5
+ attr_accessor :parent, :elements, :offset, :text_value
6
+
7
+ def initialize(text_value, offset, elements = nil)
8
+ @parent = nil
9
+ @elements = elements
10
+ @offset = offset
11
+ @text_value = text_value
12
+ elements.each do |element|
13
+ element.parent = self
14
+ end unless(elements.nil?)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,70 @@
1
+ module KoiReferenceCompiler
2
+
3
+ # 0
4
+ PUSH_NIL = 0
5
+ PUSH_BOOL = 1
6
+ PUSH_INT = 2
7
+ PUSH_FLOAT = 3
8
+ PUSH_STRING = 4
9
+
10
+ # 20
11
+ JUMP = 20
12
+ JUMP_IF = 21
13
+ JUMP_UNLESS = 22
14
+
15
+ # 40
16
+ POP = 40
17
+ SWAP = 41
18
+ DUP = 42
19
+ STKSIZE = 43
20
+ TYPEOF = 44
21
+ TOP = 45
22
+
23
+ # 60
24
+ ADD = 60
25
+ SUBTRACT = 61
26
+ MULTIPLY = 62
27
+ DIVIDE = 63
28
+
29
+ # 80
30
+ CONCAT = 80
31
+ STRLEN = 81
32
+ TO_STRING = 82
33
+
34
+ # 100
35
+ EQUAL = 100
36
+ LESS_THAN = 101
37
+ GREATER_THAN = 102
38
+ INVERT = 103
39
+
40
+ # 120
41
+ PRINT = 120
42
+ GETS = 121
43
+
44
+ # 140
45
+ SET_LOCAL = 140
46
+ GET_LOCAL = 141
47
+ SET_GLOBAL = 142
48
+ GET_GLOBAL = 143
49
+
50
+ # 160
51
+ PUSH_FUNCTION = 160
52
+ END_FUNCTION = 161
53
+ CALL = 162
54
+ RETURN = 163
55
+ TAILCALL = 164
56
+
57
+ # 180
58
+ PUSH_HASH = 180
59
+ SET_KEY = 181
60
+ GET_KEY = 182
61
+ HAS_KEY = 183
62
+ LENGTH = 184
63
+ NUM_PAIRS = 185
64
+ PAIRS = 186
65
+
66
+ # 240
67
+ NO_OP = 240
68
+ EXIT = 255
69
+
70
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
2
+
3
+ class AstHashLoaderTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceCompiler
6
+
7
+ test "should turn AST hash into object" do
8
+ ast_hash = {
9
+ :parent => nil,
10
+ :elements => nil,
11
+ :offset => 0,
12
+ :name => "Identifier",
13
+ :text_value => "test"
14
+ }
15
+ tree = Compiler.load_ast_hash(ast_hash)
16
+ assert_kind_of Identifier, tree
17
+ assert_equal nil, tree.parent
18
+ assert_equal nil, tree.elements
19
+ assert_equal 0, tree.offset
20
+ assert_equal "test", tree.text_value
21
+ end
22
+
23
+ test "should turn nested AST hash into nested objects" do
24
+ built_hash = {
25
+ :parent => nil,
26
+ :elements => nil,
27
+ :offset => 0,
28
+ :name => "Assignment",
29
+ :text_value => "test = 1"
30
+ }
31
+ built_hash[:elements] = [
32
+ {
33
+ :parent => built_hash,
34
+ :elements => nil,
35
+ :offset => 0,
36
+ :name => "Identifier",
37
+ :text_value => "test"
38
+ }
39
+ ]
40
+ tree = Compiler.load_ast_hash(built_hash)
41
+ assert_kind_of Assignment, tree
42
+ assert_kind_of Identifier, tree.elements.first
43
+ assert_equal tree, tree.elements.first.parent
44
+ end
45
+
46
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'test_helper.rb'))
2
+
3
+ class AssignmentTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceCompiler
6
+
7
+ test "should compile Assignment" do
8
+ tree = Assignment.new("test = 1", 0, [
9
+ Identifier.new("test", 0),
10
+ AssignmentOperator.new("=", 5),
11
+ Expression.new("1", 7, [
12
+ IntegerLiteral.new("1", 7)
13
+ ])
14
+ ])
15
+ bytecode = tree.compile
16
+ assert_equal [
17
+ PUSH_INT, 1,
18
+ SET_LOCAL, :test
19
+ ], bytecode
20
+ end
21
+
22
+ end
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'test_helper.rb'))
2
+
3
+ class BlockTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceCompiler
6
+
7
+ test "should compile Block" do
8
+ tree = Block.new("test = 1\ntest2 = 2", 0, [
9
+ Statement.new("test = 1\n", 0, [
10
+ Assignment.new("test = 1", 0, [
11
+ Identifier.new("test", 0),
12
+ AssignmentOperator.new("=", 5),
13
+ Expression.new("1", 7, [
14
+ IntegerLiteral.new("1", 7)
15
+ ])
16
+ ])
17
+ ]),
18
+ Statement.new("test2 = 2", 10, [
19
+ Assignment.new("test2 = 2", 10, [
20
+ Identifier.new("test2", 9),
21
+ AssignmentOperator.new("=", 15),
22
+ Expression.new("2", 17, [
23
+ IntegerLiteral.new("2", 17)
24
+ ])
25
+ ])
26
+ ])
27
+ ])
28
+ bytecode = tree.compile
29
+ assert_equal [
30
+ PUSH_INT, 1,
31
+ SET_LOCAL, :test,
32
+ PUSH_INT, 2,
33
+ SET_LOCAL, :test2
34
+ ], bytecode
35
+ end
36
+
37
+ end