flea 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/.gitignore +1 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +274 -0
  4. data/Rakefile +36 -0
  5. data/VERSION +1 -0
  6. data/bin/flea +39 -0
  7. data/examples/guess-the-number.scm +18 -0
  8. data/flea-language-spec/README.rdoc +3 -0
  9. data/flea-language-spec/flea-language-spec.yaml +2 -0
  10. data/flea-language-spec/test-cases/01-display-and-basic-literals/01-display-string-literal.scm +5 -0
  11. data/flea-language-spec/test-cases/01-display-and-basic-literals/02-display-integer-literal.scm +5 -0
  12. data/flea-language-spec/test-cases/01-display-and-basic-literals/03-display-boolean-true-literal.scm +5 -0
  13. data/flea-language-spec/test-cases/01-display-and-basic-literals/04-display-boolean-false-literal.scm +5 -0
  14. data/flea-language-spec/test-cases/01-display-and-basic-literals/05-display-list-literal-using-quote.scm +5 -0
  15. data/flea-language-spec/test-cases/01-display-and-basic-literals/06-display-identifier-quoted.scm +5 -0
  16. data/flea-language-spec/test-cases/02-variables/01-define-with-string.scm +6 -0
  17. data/flea-language-spec/test-cases/02-variables/02-define-with-integer.scm +6 -0
  18. data/flea-language-spec/test-cases/02-variables/03-define-with-boolean-true.scm +6 -0
  19. data/flea-language-spec/test-cases/02-variables/04-define-with-boolean-false.scm +6 -0
  20. data/flea-language-spec/test-cases/02-variables/05-define-with-list.scm +6 -0
  21. data/flea-language-spec/test-cases/03-basic-built-in-procedures/01-addition.scm +5 -0
  22. data/flea-language-spec/test-cases/03-basic-built-in-procedures/02-subtraction.scm +5 -0
  23. data/flea-language-spec/test-cases/03-basic-built-in-procedures/03-multiplication.scm +5 -0
  24. data/flea-language-spec/test-cases/03-basic-built-in-procedures/04-division.scm +5 -0
  25. data/flea-language-spec/test-cases/03-basic-built-in-procedures/05-equality-true-integer.scm +5 -0
  26. data/flea-language-spec/test-cases/03-basic-built-in-procedures/06-equality-false-integer.scm +5 -0
  27. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/01-equal?-true-integer.scm +5 -0
  28. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/02-equal?-false-integer.scm +5 -0
  29. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/03-equal?-true-string.scm +5 -0
  30. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/04-equal?-false-string.scm +5 -0
  31. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/05-equal?-true-boolean.scm +5 -0
  32. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/06-equal?-false-boolean.scm +5 -0
  33. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/07-equal?-true-list.scm +7 -0
  34. data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/08-equal?-false-list.scm +7 -0
  35. data/flea-language-spec/test-cases/04-comma-quoting/01-comma-quoting.scm +5 -0
  36. data/flea-language-spec/test-cases/05-lambda/01-lambda.scm +5 -0
  37. data/flea-language-spec/test-cases/05-lambda/02-call-in-place-lambda.scm +5 -0
  38. data/flea-language-spec/test-cases/05-lambda/03-define-with-lambda.scm +6 -0
  39. data/flea-language-spec/test-cases/05-lambda/04-define-and-call-lambda.scm +8 -0
  40. data/flea-language-spec/test-cases/05-lambda/05-lambda-repeated-argument.scm +9 -0
  41. data/flea-language-spec/test-cases/05-lambda/06-lambda-list-argument.scm +8 -0
  42. data/flea-language-spec/test-cases/05-lambda/07-lambda-n-or-more-arguments.scm +12 -0
  43. data/flea-language-spec/test-cases/05-lambda/08-lambda-should-return-last-result.scm +16 -0
  44. data/flea-language-spec/test-cases/06-if/01-if-true-single-arg.scm +6 -0
  45. data/flea-language-spec/test-cases/06-if/02-if-false-single-arg.scm +6 -0
  46. data/flea-language-spec/test-cases/06-if/03-if-true-two-args.scm +7 -0
  47. data/flea-language-spec/test-cases/06-if/04-if-false-two-args.scm +7 -0
  48. data/flea-language-spec/test-cases/07-set/01-should-not-set-undefined-variable.scm +5 -0
  49. data/flea-language-spec/test-cases/07-set/02-set-previously-defined-variable.scm +8 -0
  50. data/flea-language-spec/test-cases/08-derived-expressions/01-begin/01-begin.scm +8 -0
  51. data/flea-language-spec/test-cases/09-list-manipulation/01-car.scm +7 -0
  52. data/flea-language-spec/test-cases/09-list-manipulation/02-cdr.scm +7 -0
  53. data/flea-language-spec/test-cases/09-list-manipulation/03-list-tail.scm +7 -0
  54. data/flea-language-spec/test-cases/09-list-manipulation/04-append.scm +10 -0
  55. data/flea-language-spec/test-cases/09-list-manipulation/05-list.scm +5 -0
  56. data/flea-language-spec/test-cases/10-functional-examples/countdown.scm +15 -0
  57. data/lib/flea.rb +5 -0
  58. data/lib/flea/environment.rb +38 -0
  59. data/lib/flea/interpreter.rb +67 -0
  60. data/lib/flea/standard_library/addition_operator.scm +7 -0
  61. data/lib/flea/standard_library/append.scm +7 -0
  62. data/lib/flea/standard_library/begin.scm +11 -0
  63. data/lib/flea/standard_library/car.scm +7 -0
  64. data/lib/flea/standard_library/cdr.scm +7 -0
  65. data/lib/flea/standard_library/cons.scm +13 -0
  66. data/lib/flea/standard_library/display.scm +8 -0
  67. data/lib/flea/standard_library/division_operator.scm +7 -0
  68. data/lib/flea/standard_library/equality_operator.scm +8 -0
  69. data/lib/flea/standard_library/gets.scm +6 -0
  70. data/lib/flea/standard_library/greater_than.scm +8 -0
  71. data/lib/flea/standard_library/if.scm +10 -0
  72. data/lib/flea/standard_library/lambda.scm +57 -0
  73. data/lib/flea/standard_library/less_than.scm +8 -0
  74. data/lib/flea/standard_library/list.scm +8 -0
  75. data/lib/flea/standard_library/list_predicate.scm +6 -0
  76. data/lib/flea/standard_library/list_tail.scm +5 -0
  77. data/lib/flea/standard_library/multiplication_operator.scm +7 -0
  78. data/lib/flea/standard_library/null.scm +3 -0
  79. data/lib/flea/standard_library/quote.scm +6 -0
  80. data/lib/flea/standard_library/rand.scm +6 -0
  81. data/lib/flea/standard_library/read.scm +6 -0
  82. data/lib/flea/standard_library/set.scm +9 -0
  83. data/lib/flea/standard_library/string_to_num.scm +6 -0
  84. data/lib/flea/standard_library/subtraction_operator.scm +7 -0
  85. data/spec/flea/environment_spec.rb +114 -0
  86. data/spec/flea/interpreter_spec.rb +85 -0
  87. data/spec/flea/standard_library/addition_operator_spec.rb +23 -0
  88. data/spec/flea/standard_library/append_spec.rb +17 -0
  89. data/spec/flea/standard_library/begin_spec.rb +20 -0
  90. data/spec/flea/standard_library/car_spec.rb +17 -0
  91. data/spec/flea/standard_library/cdr_spec.rb +17 -0
  92. data/spec/flea/standard_library/cons_spec.rb +25 -0
  93. data/spec/flea/standard_library/display_spec.rb +36 -0
  94. data/spec/flea/standard_library/division_operator_spec.rb +29 -0
  95. data/spec/flea/standard_library/equality_operator_spec.rb +45 -0
  96. data/spec/flea/standard_library/gets_spec.rb +23 -0
  97. data/spec/flea/standard_library/greater_than_spec.rb +29 -0
  98. data/spec/flea/standard_library/if_spec.rb +59 -0
  99. data/spec/flea/standard_library/lambda_spec.rb +70 -0
  100. data/spec/flea/standard_library/less_than_spec.rb +29 -0
  101. data/spec/flea/standard_library/list_predicate_spec.rb +25 -0
  102. data/spec/flea/standard_library/list_spec.rb +24 -0
  103. data/spec/flea/standard_library/list_tail_spec.rb +17 -0
  104. data/spec/flea/standard_library/mutiplication_operator_spec.rb +23 -0
  105. data/spec/flea/standard_library/null_spec.rb +26 -0
  106. data/spec/flea/standard_library/quote_spec.rb +20 -0
  107. data/spec/flea/standard_library/rand_spec.rb +25 -0
  108. data/spec/flea/standard_library/read_spec.rb +23 -0
  109. data/spec/flea/standard_library/set_spec.rb +23 -0
  110. data/spec/flea/standard_library/string_to_num_spec.rb +28 -0
  111. data/spec/flea/standard_library/subtraction_operator_spec.rb +24 -0
  112. data/spec/spec_helper.rb +10 -0
  113. metadata +231 -0
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "addition operator" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "should add several numbers" do
10
+ result = @interpreter.run('(+ 1 2 3)')
11
+ result.should == 6
12
+ end
13
+
14
+ it "should evaluate its arguments before adding them" do
15
+ result = @interpreter.run('
16
+ (define a 2)
17
+ (+ a a a)
18
+ ')
19
+ result.should == 6
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "append" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "union of two lists" do
10
+ result = @interpreter.run('
11
+ (append (quote (1 2 3)) (quote (1 2 3)))
12
+ ')
13
+ result.should == [1, 2, 3, 1, 2, 3]
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "begin" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "should execute each expression after the begin call and return final value" do
10
+ result = @interpreter.run('
11
+ (begin
12
+ (define test 1)
13
+ (set! test 2))
14
+ ')
15
+ result.should == 2
16
+ @interpreter.base_environment.find(:test).should == 2
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "car" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "should return first item of list" do
10
+ result = @interpreter.run('
11
+ (car (quote (10 2 2)))
12
+ ')
13
+ result.should == 10
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "cdr" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "should return remainder of list" do
10
+ result = @interpreter.run('
11
+ (cdr (quote (10 2 2)))
12
+ ')
13
+ result.should == [2, 2]
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "cons" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "should create a list from an atom and an empty list" do
10
+ result = @interpreter.run("(cons 'a '())")
11
+ result.should == [:a]
12
+ end
13
+
14
+ it "should create a list from a pair of lists" do
15
+ result = @interpreter.run("(cons '(a) '(b c d))")
16
+ result.should == [[:a], :b, :c, :d]
17
+ end
18
+
19
+ it "should push an atom on an existing list" do
20
+ result = @interpreter.run('(cons "a" \'(b c ))')
21
+ result.should == ["a", :b, :c]
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "display" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ @old_stdout = $stdout
8
+ @buffer = StringIO.new
9
+ $stdout = @buffer
10
+ end
11
+
12
+ it "should output simple literal" do
13
+ @interpreter.run('(display 1)')
14
+ @buffer.string.should == "1"
15
+ end
16
+
17
+ it "should output a list" do
18
+ @interpreter.run('(display (quote (1 2 3)))')
19
+ @buffer.string.should == "(1 2 3)"
20
+ end
21
+
22
+ it "should output true and false using Scheme external representation" do
23
+ @interpreter.run('(display #t)(display #f)')
24
+ @buffer.string.should == "#t#f"
25
+ end
26
+
27
+ it "should return the same value that it displayed" do
28
+ result = @interpreter.run('(display "abc")')
29
+ result.should == "abc"
30
+ end
31
+
32
+ after :each do
33
+ $stdout = @old_stdout
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "division operator" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "should divide several integers" do
10
+ result = @interpreter.run('(/ 10 2 2)')
11
+ result.should == 2
12
+ end
13
+
14
+ it "should divide several floats" do
15
+ result = @interpreter.run('(/ 10.0 2 2)')
16
+ result.should == 2.5
17
+ end
18
+
19
+ it "should evaluate its arguments before dividing them" do
20
+ result = @interpreter.run('
21
+ (define a 2)
22
+ (define b 10)
23
+ (/ b a a)
24
+ ')
25
+ result.should == 2
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "equality operator" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ context "for an expression that should evaluate to true" do
10
+ it "should return the equality of several arguments" do
11
+ result = @interpreter.run('
12
+ (= 2 2 2)
13
+ ')
14
+ result.should == true
15
+ end
16
+
17
+ it "should evaluate its arguments before comparing them" do
18
+ result = @interpreter.run('
19
+ (define a 2)
20
+ (= a a a)
21
+ ')
22
+ result.should == true
23
+ end
24
+ end
25
+
26
+ context "for an expression that should evaluate to false" do
27
+ it "should return the equality of several arguments" do
28
+ result = @interpreter.run('
29
+ (= 2 2 4)
30
+ ')
31
+ result.should == false
32
+ end
33
+
34
+ it "should evaluate its arguments before comparing them" do
35
+ result = @interpreter.run('
36
+ (define a 2)
37
+ (define b 3)
38
+ (= a a b)
39
+ ')
40
+ result.should == false
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "gets" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ @old_stdin = $stdin
8
+ @buffer = StringIO.new
9
+ $stdin = @buffer
10
+ end
11
+
12
+ it "should get input from STDIN" do
13
+ @buffer.string = "test\n"
14
+ result = @interpreter.run('(gets)')
15
+ result.should == "test\n"
16
+ end
17
+
18
+ after :each do
19
+ $stdin = @old_stdin
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "greater-than?" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "return true if it's first argument is larger than all the others" do
10
+ result = @interpreter.run('(greater-than? 10 1 2 3 4)')
11
+ result.should == true
12
+ end
13
+
14
+ it "return false if it's first argument is not larger than all the others" do
15
+ result = @interpreter.run('(greater-than? 10 1 2 3 45)')
16
+ result.should == false
17
+ end
18
+
19
+ it "should evaluate its arguments" do
20
+ result = @interpreter.run('
21
+ (define a 2)
22
+ (define b 10)
23
+ (greater-than? b a a)
24
+ ')
25
+ result.should == true
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "if" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ context "only with consequent" do
10
+ it "should execute consequent" do
11
+ @interpreter.run('
12
+ (if #t
13
+ (define consequent 1))
14
+ ')
15
+ @interpreter.base_environment.should have_variable :consequent
16
+ end
17
+
18
+ it "should not execute consequent" do
19
+ @interpreter.run('
20
+ (if #f
21
+ (define consequent 1))
22
+ ')
23
+ @interpreter.base_environment.should_not have_variable :consequent
24
+ end
25
+
26
+ it "should evaluate arguments before deciding on execution" do
27
+ @interpreter.run('
28
+ (define test #t)
29
+ (if test
30
+ (define consequent 1))
31
+ ')
32
+ @interpreter.base_environment.should have_variable :consequent
33
+ end
34
+ end
35
+
36
+ context "with consequent and alternative" do
37
+ it "should execute alternative" do
38
+ @interpreter.run('
39
+ (if #f
40
+ (define consequent 1)
41
+ (define alternative 1))
42
+ ')
43
+ @interpreter.base_environment.should_not have_variable :consequent
44
+ @interpreter.base_environment.should have_variable :alternative
45
+ end
46
+
47
+ it "should execute consequent" do
48
+ @interpreter.run('
49
+ (if #t
50
+ (define consequent 1)
51
+ (define alternative 1))
52
+ ')
53
+ @interpreter.base_environment.should have_variable :consequent
54
+ @interpreter.base_environment.should_not have_variable :alternative
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,70 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "lambda" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ @old_stdout = $stdout
8
+ @buffer = StringIO.new
9
+ $stdout = @buffer
10
+ end
11
+
12
+ after :each do
13
+ $stdout = @old_stdout
14
+ end
15
+
16
+ it "should create a lambda that takes no arguments" do
17
+ result = @interpreter.run('
18
+ (lambda () ())
19
+ ')
20
+ result.should be_a Proc
21
+ end
22
+
23
+ it "should create and execute a lambda that takes no arguments" do
24
+ result = @interpreter.run('
25
+ ((lambda ()
26
+ (display 1)))
27
+ ')
28
+ result.should == 1
29
+ end
30
+
31
+ it "should create a lambda that takes a single argument" do
32
+ result = @interpreter.run('
33
+ (lambda a ())
34
+ ')
35
+ result.should be_a Proc
36
+ end
37
+
38
+ it "should take list as single argument" do
39
+ result = @interpreter.run('
40
+ ((lambda a
41
+ (display a)) 1 2 3)
42
+ ')
43
+ result.should == [1, 2, 3]
44
+ end
45
+
46
+ it "should create a lambda that takes multiple arguments" do
47
+ result = @interpreter.run('
48
+ (lambda (a b c) ())
49
+ ')
50
+ result.should be_a Proc
51
+ end
52
+
53
+ it "should create aand execute a lambda that takes multiple arguments" do
54
+ result = @interpreter.run('
55
+ ((lambda (a b c)
56
+ (display (+ a b c))) 1 2 3)
57
+ ')
58
+ result.should == 6
59
+ end
60
+
61
+ it "should raise an error when lamda is defined using same argument name more than once" do
62
+ lambda {
63
+ @interpreter.run('
64
+ (lambda (a a a) ())
65
+ ')
66
+ }.should raise_error
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Standard Library" do
4
+ describe "less-than?" do
5
+ before :each do
6
+ @interpreter = Flea::Interpreter.new
7
+ end
8
+
9
+ it "return true if it's first argument is smaller than all the others" do
10
+ result = @interpreter.run('(less-than? 5 10 15 20)')
11
+ result.should == true
12
+ end
13
+
14
+ it "return false if it's first argument is not smaller than all the others" do
15
+ result = @interpreter.run('(less-than? 10 1 2 3 45)')
16
+ result.should == false
17
+ end
18
+
19
+ it "should evaluate its arguments" do
20
+ result = @interpreter.run('
21
+ (define a 2)
22
+ (define b 10)
23
+ (less-than? b a a)
24
+ ')
25
+ result.should == false
26
+ end
27
+
28
+ end
29
+ end