lucio 0.0.7

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.
@@ -0,0 +1,92 @@
1
+ require 'lucio/grammar'
2
+
3
+ grammar Lucio
4
+
5
+ rule lucio
6
+ (whitespace / (quote? list))* <Grammar>
7
+ end
8
+
9
+ rule list
10
+ lparen (whitespace / operator)? (value)* rparen
11
+ end
12
+
13
+ rule value
14
+ list / string / number / boolean / operator / vector / whitespace
15
+ end
16
+
17
+ rule quote
18
+ '\''
19
+ end
20
+
21
+ rule rparen
22
+ ')'
23
+ end
24
+
25
+ rule lparen
26
+ '('
27
+ end
28
+
29
+ rule whitespace
30
+ [ \n\r\t,]+
31
+ end
32
+
33
+ rule vector
34
+ '[' (value)* ']'
35
+ end
36
+
37
+ rule operator
38
+ ((([a-zA-Z] ([-]? [a-zA-Z0-9])* [?]?) !('+' / '-' / '/' / '*')) / ('+' / '-' / '/' / '*')) {
39
+ def value
40
+ text_value
41
+ end
42
+ }
43
+ end
44
+
45
+ rule number
46
+ decimal / integer {
47
+ def value
48
+ f = text_value.to_f
49
+ i = text_value.to_i
50
+ (f - i == 0 ? i : f)
51
+ end
52
+ }
53
+ end
54
+
55
+ rule decimal
56
+ integer '.' [0-9]+ {
57
+ def value
58
+ text_value.to_f
59
+ end
60
+ }
61
+ end
62
+
63
+ rule integer
64
+ '-'? unsigned_integer
65
+ end
66
+
67
+ rule unsigned_integer
68
+ '0' / [1-9] [0-9]*
69
+ end
70
+
71
+ rule string
72
+ '"' [^"]* '"' {
73
+ def value
74
+ text_value
75
+ end
76
+ }
77
+ end
78
+ #'
79
+ rule boolean
80
+ true / false
81
+ end
82
+
83
+ rule true
84
+ 'true'
85
+ end
86
+
87
+ rule false
88
+ 'false'
89
+ end
90
+
91
+ end
92
+
data/lucio.gemspec ADDED
@@ -0,0 +1,104 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{lucio}
8
+ s.version = "0.0.7"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["pbalduino"]
12
+ s.date = %q{2011-07-15}
13
+ s.description = %q{Lucio is intended to be a Lisp-like language developed in Ruby only for knowledge and fun.}
14
+ s.email = %q{pbalduino+github@gmail.com}
15
+ s.executables = ["lucio", "repl.rb"]
16
+ s.extra_rdoc_files = [
17
+ "CHANGELOG.md",
18
+ "LICENSE.txt",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".autotest",
23
+ ".document",
24
+ ".rspec",
25
+ ".rvmrc",
26
+ "CHANGELOG.md",
27
+ "Gemfile",
28
+ "Gemfile.lock",
29
+ "LICENSE.txt",
30
+ "README.md",
31
+ "Rakefile",
32
+ "TODO.md",
33
+ "VERSION",
34
+ "bin/lucio",
35
+ "bin/repl.rb",
36
+ "lib/lucio.rb",
37
+ "lib/lucio/grammar.rb",
38
+ "lib/lucio/lexicon.rb",
39
+ "lib/lucio/list.rb",
40
+ "lib/lucio/lucio.rb",
41
+ "lib/lucio/operators.rb",
42
+ "lib/lucio/operators/attribution.rb",
43
+ "lib/lucio/operators/conditional.rb",
44
+ "lib/lucio/operators/division.rb",
45
+ "lib/lucio/operators/equality.rb",
46
+ "lib/lucio/operators/macro.rb",
47
+ "lib/lucio/operators/multiplication.rb",
48
+ "lib/lucio/operators/operator.rb",
49
+ "lib/lucio/operators/subtraction.rb",
50
+ "lib/lucio/operators/sum.rb",
51
+ "lib/lucio/runner.rb",
52
+ "lib/lucio_syntax.treetop",
53
+ "lucio.gemspec",
54
+ "spec/all_the_fun_spec.rb",
55
+ "spec/division_spec.rb",
56
+ "spec/eval_spec.rb",
57
+ "spec/lucio_spec.rb",
58
+ "spec/multiplication_spec.rb",
59
+ "spec/parser_spec.rb",
60
+ "spec/spec_helper.rb",
61
+ "spec/subtraction_spec.rb",
62
+ "spec/sum_spec.rb",
63
+ "spec/variable_spec.rb"
64
+ ]
65
+ s.homepage = %q{https://github.com/pbalduino/lucio}
66
+ s.licenses = ["MIT"]
67
+ s.require_paths = ["lib"]
68
+ s.rubygems_version = %q{1.5.2}
69
+ s.summary = %q{Lucio is a LISP-like language created just for fun}
70
+
71
+ if s.respond_to? :specification_version then
72
+ s.specification_version = 3
73
+
74
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
75
+ s.add_runtime_dependency(%q<polyglot>, [">= 0"])
76
+ s.add_runtime_dependency(%q<treetop>, [">= 0"])
77
+ s.add_development_dependency(%q<rspec>, [">= 0"])
78
+ s.add_development_dependency(%q<ZenTest>, [">= 0"])
79
+ s.add_development_dependency(%q<diff-lcs>, [">= 0"])
80
+ s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
81
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
82
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
83
+ else
84
+ s.add_dependency(%q<polyglot>, [">= 0"])
85
+ s.add_dependency(%q<treetop>, [">= 0"])
86
+ s.add_dependency(%q<rspec>, [">= 0"])
87
+ s.add_dependency(%q<ZenTest>, [">= 0"])
88
+ s.add_dependency(%q<diff-lcs>, [">= 0"])
89
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
90
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
91
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
92
+ end
93
+ else
94
+ s.add_dependency(%q<polyglot>, [">= 0"])
95
+ s.add_dependency(%q<treetop>, [">= 0"])
96
+ s.add_dependency(%q<rspec>, [">= 0"])
97
+ s.add_dependency(%q<ZenTest>, [">= 0"])
98
+ s.add_dependency(%q<diff-lcs>, [">= 0"])
99
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
100
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
101
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
102
+ end
103
+ end
104
+
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe "All the fun" do
5
+ it "should have all the fun" do
6
+ Lucio.literal("'(lisp programmers have all defun)").should == '(lisp programmers have all defun)'
7
+ end
8
+
9
+ it "should work too =P" do
10
+ Lucio.literal("'(a b c)").should == '(a b c)'
11
+ end
12
+
13
+ it "should work with numbers" do
14
+ Lucio.literal("'(1 2 3)").should == '(1 2 3)'
15
+ end
16
+
17
+ it "should work with mixed values too" do
18
+ Lucio.literal("'(a b c 1 2 3)").should == '(a b c 1 2 3)'
19
+ end
20
+
21
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe Lucio::Operator::Division do
5
+ it "an empty list should return zero" do
6
+ Lucio.eval('(/)').should == 0
7
+ end
8
+
9
+ it "a list with one item should return that item" do
10
+ Lucio.eval('(/ 1)').should == 1
11
+ Lucio.eval('(/ 2)').should == 2
12
+ end
13
+
14
+ it "a list with more than one item should eval all items" do
15
+ Lucio.eval('(/ 8 4)').should == 2
16
+ Lucio.eval('(/ 8 4 2)').should == 1
17
+ end
18
+
19
+ end
data/spec/eval_spec.rb ADDED
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe Lucio do
5
+
6
+ context 'empty list' do
7
+ it 'should return nil' do
8
+ Lucio.eval('()').should == nil
9
+ Lucio.eval('( )').should == nil
10
+ Lucio.eval('( )').should == nil
11
+ end
12
+ end
13
+
14
+ context 'sum operation' do
15
+ it 'should return a numeric value' do
16
+ Lucio.eval('(1)').should == 1
17
+ Lucio.eval('(+ 1 2)').should == 3
18
+ Lucio.eval('(+ 1 2 3 4 5 6)').should == 21
19
+ Lucio.eval('(+ 1 (+ 2 3))').should == 6
20
+
21
+ Lucio.eval('(+)').should == 0
22
+
23
+ lambda { Lucio.eval('(invalid)') }.should raise_error
24
+ end
25
+ end
26
+
27
+ context 'more than one type of operation' do
28
+ it 'should return a numeric value' do
29
+ Lucio.eval('(/ (* (+ 1 2) (+3 4)) 2)').should == 10.5
30
+ Lucio.eval('(- 10.5 (/ (* (+ 1 2) (+3 4)) 2))').should == 0
31
+ end
32
+ end
33
+
34
+ context 'builtin function' do
35
+ it 'compare two values using a function' do
36
+ Lucio.eval('(eql? (* (+ 1 2) 3) 9)').should be_true
37
+ Lucio.eval('(eql? (/ (* (+ 1 2) (+3 4)) 2) 10)').should be_false
38
+ Lucio.eval(<<lisp
39
+ (eql?
40
+ (/
41
+ (*
42
+ (+ 1 2)
43
+ (+3 4))
44
+ 2)
45
+ 10)
46
+ lisp
47
+ ).should be_false
48
+ end
49
+ end
50
+
51
+ context 'macro' do
52
+ it 'runs a simple if' do
53
+ Lucio.eval(<<lisp
54
+ (if (eql? 1 1)
55
+ ("ok"))
56
+ lisp
57
+ ).should == 'ok'
58
+ end
59
+
60
+ it 'a simple if without else returns nil when false' do
61
+ Lucio.eval('(if (eql? 1 2)("nope"))').should == nil
62
+ end
63
+
64
+ it 'runs a if with else' do
65
+ Lucio.eval(<<lisp
66
+ (if (eql? 1 1)
67
+ ("ok")
68
+ ("nope"))
69
+ lisp
70
+ ).should == 'ok'
71
+
72
+ Lucio.eval(<<lisp
73
+ (if (eql? 2 1)
74
+ ("nope")
75
+ ("ok"))
76
+ lisp
77
+ ).should == 'ok'
78
+ end
79
+
80
+ it 'runs a function before a macro' do
81
+ Lucio.eval(<<lisp
82
+ (+ 1 2 3 (if (eql? (+ 1 1) 2) (4) (5)))
83
+ lisp
84
+ ).should == 10
85
+
86
+ Lucio.eval(<<lisp
87
+ (eql? (+ 1 2 3 (if (eql? (+ 1 1) 2) (4) (5))) 10)
88
+ lisp
89
+ ).should be_true
90
+ end
91
+
92
+ it 'runs a macro before a function ' do
93
+ code = <<lisp
94
+ (if (eql? (+ 1 1) 2) (+ 1 2 3 4) (0))
95
+ lisp
96
+ Lucio.eval(code).should == 10
97
+
98
+ Lucio.eval(<<lisp
99
+ (if (eql? (+ 1 1) 2)
100
+ (eql? (+ 1 2 3 (4) (5)) 15)
101
+ (false))
102
+ lisp
103
+ ).should be_true
104
+ end
105
+ end
106
+
107
+ context 'quoted list' do
108
+
109
+ it 'a quoted empty list should return an empty list' do
110
+ Lucio.literal("'()").should == '()'
111
+
112
+ end
113
+
114
+ end
115
+
116
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe Lucio do
5
+ it "should return head and tail" do
6
+ h, t = Lucio.behead [1, 2, 3, 4, 5]
7
+ h.should == 1
8
+ t.should == [2, 3, 4, 5]
9
+ end
10
+
11
+ it "should return empty tail" do
12
+ h, t = Lucio.behead [1]
13
+ h.should == 1
14
+ t.should == []
15
+ end
16
+
17
+ it "should handle empty collections" do
18
+ h, t = Lucio.behead []
19
+ h.should == nil
20
+ t.should == []
21
+ end
22
+
23
+
24
+ end
25
+
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe Lucio::Operator::Multiplication do
5
+ it "an empty list should return zero" do
6
+ Lucio.eval('(*)').should == 0
7
+ end
8
+
9
+ it "a list with one item should return that item" do
10
+ Lucio.eval('(* 1)').should == 1
11
+ Lucio.eval('(* 2)').should == 2
12
+ end
13
+
14
+ it "a list with more than one item should eval all items" do
15
+ Lucio.eval('(* 2 3)').should == 6
16
+ Lucio.eval('(* 2 3 4)').should == 24
17
+ end
18
+
19
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe Lucio do
5
+
6
+ context "list" do
7
+ it "integer" do
8
+ Lucio.parse('(2)').should be
9
+ end
10
+
11
+ it "integers" do
12
+ Lucio.parse('(2)(3)').should be
13
+ end
14
+
15
+ it "decimal" do
16
+ Lucio.parse('(3.14)').should be
17
+ end
18
+
19
+ it "valid string" do
20
+ Lucio.parse('("this is a text")').should be
21
+ end
22
+
23
+ it "valid expression" do
24
+ Lucio.parse('(this is an expression)').should be
25
+ end
26
+
27
+ it "boolean" do
28
+ Lucio.parse('(true)').should be
29
+ Lucio.parse('(true)').should be
30
+ Lucio.parse('(true)(false)').should be
31
+
32
+ Lucio.parse('true').should_not be
33
+ Lucio.parse('false').should_not be
34
+ end
35
+
36
+ it 'space' do
37
+ Lucio.parse('()').should be
38
+ Lucio.parse('( )').should be
39
+ Lucio.parse('( )').should be
40
+ end
41
+
42
+ it 'simple expression' do
43
+ Lucio.parse('(+ 1 2)').should be
44
+ end
45
+
46
+ it 'long expression' do
47
+ Lucio.parse('(+ 1 2 3 4)').should be
48
+ end
49
+
50
+ it 'long expression with commas' do
51
+ Lucio.parse('(+ 1, 2, 3, 4)').should be
52
+ end
53
+
54
+ it 'vector' do
55
+ Lucio.parse('([1 2 3 4 5 6])').should be
56
+ end
57
+
58
+ it 'vector with commas' do
59
+ Lucio.parse('([1, 2, 3, 4, 5, 6])').should be
60
+ end
61
+
62
+ it 'composed expression' do
63
+ Lucio.parse('(+ 1 (* 2 3))').should be
64
+ end
65
+
66
+ it 'composed long expression' do
67
+ Lucio.parse('(+ 1 2 3 (* 4 5 6))').should be
68
+ end
69
+
70
+ it 'and now we return to begin' do
71
+ Lucio.parse('(* (+ 1 2) 3)').should be
72
+
73
+ Lucio.parse('(/ (* (+ 1 2)(+ 3 4)) 2)').should be
74
+ end
75
+
76
+ it 'special caracters should work to improve the expressiveness' do
77
+ Lucio.parse('(eql? (* (+ 1 2) 3) 9)').should be
78
+
79
+ Lucio.parse('(eql?? (* (+ 1 2) 3) 9)').should_not be
80
+
81
+ Lucio.parse('(foo-bar (1 1 2 3 4 4))').should be
82
+ Lucio.parse('(foo-bar-meh (1 1 2 3 4 4))').should be
83
+
84
+ Lucio.parse('(foo--bar (1 1 2 3 4 4))').should be_nil
85
+ Lucio.parse('(foo--bar (1 1 2 3 4 4))').should_not be
86
+ Lucio.parse('(foo----- (1 1 2 3 4 4))').should_not be
87
+ Lucio.parse('(foo--bar-meh (1 1 2 3 4 4))').should_not be
88
+ end
89
+
90
+ it 'multiline' do
91
+ code = <<lisp
92
+ (/
93
+ (*
94
+ (+ 1 2)
95
+ (+ 3 4))
96
+ 2)
97
+ lisp
98
+
99
+ Lucio.parse(code).should be
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+
@@ -0,0 +1,3 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start # if ENV['COVERAGE']
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe Lucio::Operator::Subtraction do
5
+ it "an empty list should return zero" do
6
+ Lucio.eval('(-)').should == 0
7
+ end
8
+
9
+ it "a list with one item should return that item" do
10
+ Lucio.eval('(- 1)').should == -1
11
+ Lucio.eval('(- 2)').should == -2
12
+ end
13
+
14
+ it "a list with more than one item should eval all items" do
15
+ Lucio.eval('(- 2 1)').should == 1
16
+ Lucio.eval('(- 3 2 1)').should == 0
17
+ end
18
+
19
+ end
data/spec/sum_spec.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe Lucio::Operator::Sum do
5
+ it "an empty list should return zero" do
6
+ Lucio.eval('(+)').should == 0
7
+ end
8
+
9
+ it "a list with one item should return that item" do
10
+ Lucio.eval('(+ 1)').should == 1
11
+ Lucio.eval('(+ 2)').should == 2
12
+ end
13
+
14
+ it "a list with more than one item should eval all items" do
15
+ Lucio.eval('(+ 1 2)').should == 3
16
+ Lucio.eval('(+ 1 2 3)').should == 6
17
+ end
18
+
19
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+ require 'lucio'
3
+
4
+ describe 'Var' do
5
+ it 'should store some value' do
6
+ code = <<lisp
7
+ ((let x 3)
8
+ (x))
9
+ lisp
10
+
11
+ p Lucio.eval(code)
12
+ end
13
+ end