skeem 0.2.21 → 0.2.22
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +33 -337
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +1 -1
- data/lib/skeem/grammar.rb +13 -13
- data/lib/skeem/interpreter.rb +1 -1
- data/lib/skeem/primitive/primitive_builder.rb +1 -1
- data/lib/skeem/primitive/primitive_procedure.rb +1 -1
- data/lib/skeem/runtime.rb +2 -0
- data/lib/skeem/s_expr_nodes.rb +5 -3
- data/lib/skeem/tokenizer.rb +15 -20
- data/lib/skeem/version.rb +1 -1
- data/lib/skeem.rb +2 -2
- data/skeem.gemspec +8 -5
- data/spec/skeem/datum_dsl_spec.rb +50 -50
- data/spec/skeem/element_visitor_spec.rb +108 -108
- data/spec/skeem/interpreter_spec.rb +171 -169
- data/spec/skeem/lambda_spec.rb +27 -27
- data/spec/skeem/parser_spec.rb +27 -25
- data/spec/skeem/primitive/primitive_builder_spec.rb +127 -131
- data/spec/skeem/primitive/primitive_procedure_spec.rb +28 -28
- data/spec/skeem/runtime_spec.rb +52 -51
- data/spec/skeem/s_expr_nodes_spec.rb +31 -31
- data/spec/skeem/skm_compound_datum_spec.rb +36 -35
- data/spec/skeem/skm_element_spec.rb +35 -34
- data/spec/skeem/skm_empty_list_spec.rb +19 -19
- data/spec/skeem/skm_frame_spec.rb +49 -46
- data/spec/skeem/skm_pair_spec.rb +93 -93
- data/spec/skeem/skm_procedure_exec_spec.rb +11 -11
- data/spec/skeem/skm_simple_datum_spec.rb +102 -95
- data/spec/skeem/skm_unary_expression_spec.rb +60 -61
- data/spec/skeem/tokenizer_spec.rb +52 -52
- data/spec/skeem_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -2
- metadata +62 -18
    
        data/spec/skeem/lambda_spec.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ require_relative '../../lib/skeem/interpreter' | |
| 7 7 |  | 
| 8 8 | 
             
            module Skeem
         | 
| 9 9 | 
             
              describe 'The interpreter and compound procedures' do
         | 
| 10 | 
            -
                subject do
         | 
| 10 | 
            +
                subject(:interpreter) do
         | 
| 11 11 | 
             
                  # We load the interpreter with the primitive procedures only
         | 
| 12 12 | 
             
                  Interpreter.new { |interp| interp.add_primitives(interp.runtime) }
         | 
| 13 13 | 
             
                end
         | 
| @@ -30,85 +30,85 @@ SKEEM | |
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 32 | 
             
                context 'Defining compound procedures:' do
         | 
| 33 | 
            -
                  it ' | 
| 33 | 
            +
                  it 'accepts the definition of simple procedure with arity 1' do
         | 
| 34 34 | 
             
                    source = "#{definition_set}\nsquare"
         | 
| 35 | 
            -
                    result =  | 
| 35 | 
            +
                    result = interpreter.run(source)
         | 
| 36 36 |  | 
| 37 37 | 
             
                    square = result.last
         | 
| 38 | 
            -
                    expect(square).to  | 
| 38 | 
            +
                    expect(square).to be_a(SkmLambda)
         | 
| 39 39 | 
             
                    expect(square.arity).to eq(1)
         | 
| 40 | 
            -
                    expect(square.environment).to eq( | 
| 40 | 
            +
                    expect(square.environment).to eq(interpreter.runtime.environment)
         | 
| 41 41 | 
             
                  end
         | 
| 42 42 |  | 
| 43 | 
            -
                  it ' | 
| 43 | 
            +
                  it 'accepts the definition of simple procedure with arity 2' do
         | 
| 44 44 | 
             
                    source = "#{definition_set}\nsum-of-squares"
         | 
| 45 | 
            -
                    result =  | 
| 45 | 
            +
                    result = interpreter.run(source)
         | 
| 46 46 |  | 
| 47 47 | 
             
                    square = result.last
         | 
| 48 | 
            -
                    expect(square).to  | 
| 48 | 
            +
                    expect(square).to be_a(SkmLambda)
         | 
| 49 49 | 
             
                    expect(square.arity).to eq(2)
         | 
| 50 | 
            -
                    expect(square.environment).to eq( | 
| 50 | 
            +
                    expect(square.environment).to eq(interpreter.runtime.environment)
         | 
| 51 51 | 
             
                  end
         | 
| 52 52 | 
             
                end # context
         | 
| 53 53 |  | 
| 54 54 | 
             
                context 'Calling compound procedures:' do
         | 
| 55 | 
            -
                  it ' | 
| 55 | 
            +
                  it 'supports the call to a simple procedure with arity 1' do
         | 
| 56 56 | 
             
                    # Case 1: argument is a simple datum
         | 
| 57 | 
            -
                     | 
| 58 | 
            -
                    result =  | 
| 57 | 
            +
                    interpreter.run(definition_set)
         | 
| 58 | 
            +
                    result = interpreter.run('(square 2)')
         | 
| 59 59 | 
             
                    expect(result).to eq(4)
         | 
| 60 60 |  | 
| 61 61 | 
             
                    # Case 2: argument is a sub-expression
         | 
| 62 | 
            -
                    ptree =  | 
| 62 | 
            +
                    ptree = interpreter.parse('(square (+ 2 1))')
         | 
| 63 63 | 
             
                    proc_call = ptree.root
         | 
| 64 | 
            -
                    expect(proc_call.evaluate( | 
| 64 | 
            +
                    expect(proc_call.evaluate(interpreter.runtime)).to eq(9)
         | 
| 65 65 | 
             
                  end
         | 
| 66 66 |  | 
| 67 | 
            -
                  it ' | 
| 67 | 
            +
                  it 'supports the call to a simple procedure with arity 2' do
         | 
| 68 68 | 
             
                    source = "#{definition_set}\n(sum-of-squares 3 4)"
         | 
| 69 | 
            -
                    result =  | 
| 69 | 
            +
                    result = interpreter.run(source)
         | 
| 70 70 |  | 
| 71 71 | 
             
                    expect(result.last).to eq(25)
         | 
| 72 72 | 
             
                  end
         | 
| 73 73 |  | 
| 74 | 
            -
                  it ' | 
| 74 | 
            +
                  it 'supports the call to a nested lambda procedure' do
         | 
| 75 75 | 
             
                    source = "#{definition_set}\n(f 5)"
         | 
| 76 | 
            -
                    result =  | 
| 76 | 
            +
                    result = interpreter.run(source)
         | 
| 77 77 |  | 
| 78 78 | 
             
                    expect(result.last).to eq(136)
         | 
| 79 79 | 
             
                  end
         | 
| 80 80 |  | 
| 81 | 
            -
                  it ' | 
| 81 | 
            +
                  it 'accepts calls to anonymous procedures' do
         | 
| 82 82 | 
             
                    source = '((lambda (x) (+ x x)) 4)'
         | 
| 83 | 
            -
                    result =  | 
| 83 | 
            +
                    result = interpreter.run(source)
         | 
| 84 84 | 
             
                    expect(result).to eq(8)
         | 
| 85 85 | 
             
                  end
         | 
| 86 86 |  | 
| 87 | 
            -
                  it ' | 
| 87 | 
            +
                  it 'accepts unary second-order lambdas' do
         | 
| 88 88 | 
             
                    source = <<-SKEEM
         | 
| 89 89 | 
             
              (define add-with
         | 
| 90 90 | 
             
                (lambda (x) (lambda (y) (+ x y)))
         | 
| 91 91 | 
             
              )
         | 
| 92 92 | 
             
              (define add4 (add-with 4))
         | 
| 93 93 | 
             
            SKEEM
         | 
| 94 | 
            -
                     | 
| 95 | 
            -
                    result =  | 
| 94 | 
            +
                    interpreter.run(source)
         | 
| 95 | 
            +
                    result = interpreter.run('(add4 3)')
         | 
| 96 96 | 
             
                    expect(result).to eq(7)
         | 
| 97 97 | 
             
                  end
         | 
| 98 98 | 
             
                end # context
         | 
| 99 99 |  | 
| 100 100 | 
             
                context 'More advanced features:' do
         | 
| 101 | 
            -
                  subject { Interpreter.new }
         | 
| 101 | 
            +
                  subject(:interpreter) { Interpreter.new }
         | 
| 102 102 |  | 
| 103 | 
            -
                  it ' | 
| 103 | 
            +
                  it 'implements binary second-order functions' do
         | 
| 104 104 | 
             
                    source = <<-SKEEM
         | 
| 105 105 | 
             
              (define compose
         | 
| 106 106 | 
             
                (lambda (f g)
         | 
| 107 107 | 
             
                  (lambda (x)
         | 
| 108 108 | 
             
                    (f (g x)))))
         | 
| 109 109 | 
             
            SKEEM
         | 
| 110 | 
            -
                     | 
| 111 | 
            -
                    result =  | 
| 110 | 
            +
                    interpreter.run(source)
         | 
| 111 | 
            +
                    result = interpreter.run('((compose list square) 5)')
         | 
| 112 112 | 
             
                    expect(result.last).to eq(25)
         | 
| 113 113 | 
             
                  end
         | 
| 114 114 | 
             
                end # context
         | 
    
        data/spec/skeem/parser_spec.rb
    CHANGED
    
    | @@ -5,18 +5,20 @@ require_relative '../../lib/skeem/tokenizer' # Load the class under test | |
| 5 5 |  | 
| 6 6 | 
             
            module Skeem
         | 
| 7 7 | 
             
              describe Parser do
         | 
| 8 | 
            +
                subject(:parser) { described_class.new }
         | 
| 9 | 
            +
             | 
| 8 10 | 
             
                context 'Initialization:' do
         | 
| 9 | 
            -
                  it ' | 
| 10 | 
            -
                    expect {  | 
| 11 | 
            +
                  it 'is initialized without argument' do
         | 
| 12 | 
            +
                    expect { described_class.new }.not_to raise_error
         | 
| 11 13 | 
             
                  end
         | 
| 12 14 |  | 
| 13 | 
            -
                  it ' | 
| 14 | 
            -
                    expect( | 
| 15 | 
            +
                  it 'has its parse engine initialized' do
         | 
| 16 | 
            +
                    expect(parser.engine).to be_a(Rley::Engine)
         | 
| 15 17 | 
             
                  end
         | 
| 16 18 | 
             
                end # context
         | 
| 17 19 |  | 
| 18 20 | 
             
                context 'Parsing literals:' do
         | 
| 19 | 
            -
                  it ' | 
| 21 | 
            +
                  it 'parses isolated booleans' do
         | 
| 20 22 | 
             
                    samples = [
         | 
| 21 23 | 
             
                      ['#f', false]
         | 
| 22 24 | 
             
            #        ['#false', false],
         | 
| @@ -24,13 +26,13 @@ module Skeem | |
| 24 26 | 
             
            #        ['#true', true]
         | 
| 25 27 | 
             
                    ]
         | 
| 26 28 | 
             
                    samples.each do |source, predicted|
         | 
| 27 | 
            -
                      ptree =  | 
| 28 | 
            -
                      expect(ptree.root).to  | 
| 29 | 
            +
                      ptree = parser.parse(source)
         | 
| 30 | 
            +
                      expect(ptree.root).to be_a(SkmBoolean)
         | 
| 29 31 | 
             
                      expect(ptree.root.value).to eq(predicted)
         | 
| 30 32 | 
             
                    end
         | 
| 31 33 | 
             
                  end
         | 
| 32 34 |  | 
| 33 | 
            -
                  it ' | 
| 35 | 
            +
                  it 'parses isolated integers' do
         | 
| 34 36 | 
             
                    samples = [
         | 
| 35 37 | 
             
                      ['0', 0],
         | 
| 36 38 | 
             
                      ['3', 3],
         | 
| @@ -39,14 +41,14 @@ module Skeem | |
| 39 41 | 
             
                      ['-12345', -12345]
         | 
| 40 42 | 
             
                    ]
         | 
| 41 43 | 
             
                    samples.each do |source, predicted|
         | 
| 42 | 
            -
                      ptree =  | 
| 43 | 
            -
                      expect(ptree.root).to  | 
| 44 | 
            +
                      ptree = parser.parse(source)
         | 
| 45 | 
            +
                      expect(ptree.root).to be_a(SkmInteger)
         | 
| 44 46 | 
             
                      expect(ptree.root.value).to eq(predicted)
         | 
| 45 47 | 
             
                    end
         | 
| 46 48 | 
             
                  end
         | 
| 47 49 |  | 
| 48 50 | 
             
                  # rubocop: disable Style/ExponentialNotation
         | 
| 49 | 
            -
                  it ' | 
| 51 | 
            +
                  it 'parses isolated real numbers' do
         | 
| 50 52 | 
             
                    samples = [
         | 
| 51 53 | 
             
                      ['0.0', 0.0],
         | 
| 52 54 | 
             
                      ['3.14', 3.14],
         | 
| @@ -55,42 +57,42 @@ module Skeem | |
| 55 57 | 
             
                      ['-123e-45', -123e-45]
         | 
| 56 58 | 
             
                    ]
         | 
| 57 59 | 
             
                    samples.each do |source, predicted|
         | 
| 58 | 
            -
                      ptree =  | 
| 59 | 
            -
                      expect(ptree.root).to  | 
| 60 | 
            +
                      ptree = parser.parse(source)
         | 
| 61 | 
            +
                      expect(ptree.root).to be_a(SkmReal)
         | 
| 60 62 | 
             
                      expect(ptree.root.value).to eq(predicted)
         | 
| 61 63 | 
             
                    end
         | 
| 62 64 | 
             
                  end
         | 
| 63 65 | 
             
                  # rubocop: enable Style/ExponentialNotation
         | 
| 64 66 |  | 
| 65 | 
            -
                  it ' | 
| 67 | 
            +
                  it 'parses isolated strings' do
         | 
| 66 68 | 
             
                    samples = [
         | 
| 67 69 | 
             
                      ['"Hello world!"', 'Hello world!']
         | 
| 68 70 | 
             
                    ]
         | 
| 69 71 | 
             
                    samples.each do |source, predicted|
         | 
| 70 | 
            -
                      ptree =  | 
| 71 | 
            -
                      expect(ptree.root).to  | 
| 72 | 
            +
                      ptree = parser.parse(source)
         | 
| 73 | 
            +
                      expect(ptree.root).to be_a(SkmString)
         | 
| 72 74 | 
             
                      expect(ptree.root.value).to eq(predicted)
         | 
| 73 75 | 
             
                    end
         | 
| 74 76 | 
             
                  end
         | 
| 75 77 |  | 
| 76 | 
            -
                  it ' | 
| 78 | 
            +
                  it 'parses isolated identifiers' do
         | 
| 77 79 | 
             
                    samples = [
         | 
| 78 80 | 
             
                      %w[the-word-recursion-has-many-meanings the-word-recursion-has-many-meanings]
         | 
| 79 81 | 
             
                    ]
         | 
| 80 82 | 
             
                    samples.each do |source, predicted|
         | 
| 81 | 
            -
                      ptree =  | 
| 82 | 
            -
                      expect(ptree.root).to  | 
| 83 | 
            +
                      ptree = parser.parse(source)
         | 
| 84 | 
            +
                      expect(ptree.root).to be_a(SkmVariableReference)
         | 
| 83 85 | 
             
                      expect(ptree.root.value).to eq(predicted)
         | 
| 84 86 | 
             
                    end
         | 
| 85 87 | 
             
                  end
         | 
| 86 88 | 
             
                end # context
         | 
| 87 89 |  | 
| 88 | 
            -
                context 'Parsing forms:' do
         | 
| 89 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
                end # context
         | 
| 90 | 
            +
                # context 'Parsing forms:' do
         | 
| 91 | 
            +
                #   # it 'parses definitions' do
         | 
| 92 | 
            +
                #     # source = '(define r 10)'
         | 
| 93 | 
            +
                #     # expect { parser.parse(source) }.not_to raise_error
         | 
| 94 | 
            +
                #   # end
         | 
| 95 | 
            +
                # end # context
         | 
| 94 96 | 
             
              end # describe
         | 
| 95 97 | 
             
            end # module
         | 
| 96 98 |  |