skeem 0.2.15 → 0.2.19
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 +451 -195
- data/.travis.yml +27 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile +2 -0
- data/README.md +3 -2
- data/Rakefile +2 -0
- data/appveyor.yml +3 -4
- data/bin/skeem +15 -15
- data/lib/skeem/datum_dsl.rb +40 -30
- data/lib/skeem/element_visitor.rb +5 -2
- data/lib/skeem/grammar.rb +77 -54
- data/lib/skeem/interpreter.rb +9 -7
- data/lib/skeem/parser.rb +6 -4
- data/lib/skeem/primitive/primitive_builder.rb +130 -122
- data/lib/skeem/primitive/primitive_procedure.rb +23 -25
- data/lib/skeem/runtime.rb +17 -15
- data/lib/skeem/s_expr_builder.rb +39 -147
- data/lib/skeem/s_expr_nodes.rb +147 -132
- data/lib/skeem/skeem_exception.rb +1 -0
- data/lib/skeem/skm_binding.rb +9 -11
- data/lib/skeem/skm_compound_datum.rb +9 -6
- data/lib/skeem/skm_element.rb +15 -13
- data/lib/skeem/skm_empty_list.rb +6 -4
- data/lib/skeem/skm_exception.rb +9 -0
- data/lib/skeem/skm_expression.rb +3 -1
- data/lib/skeem/skm_frame.rb +3 -2
- data/lib/skeem/skm_pair.rb +26 -18
- data/lib/skeem/skm_procedure_exec.rb +11 -6
- data/lib/skeem/skm_simple_datum.rb +23 -20
- data/lib/skeem/skm_unary_expression.rb +34 -37
- data/lib/skeem/tokenizer.rb +40 -30
- data/lib/skeem/version.rb +3 -1
- data/lib/skeem.rb +2 -0
- data/skeem.gemspec +7 -5
- data/spec/skeem/add4.skm +4 -0
- data/spec/skeem/datum_dsl_spec.rb +13 -12
- data/spec/skeem/element_visitor_spec.rb +14 -10
- data/spec/skeem/interpreter_spec.rb +76 -46
- data/spec/skeem/lambda_spec.rb +13 -11
- data/spec/skeem/parser_spec.rb +23 -19
- data/spec/skeem/primitive/primitive_builder_spec.rb +55 -46
- data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
- data/spec/skeem/runtime_spec.rb +20 -18
- data/spec/skeem/s_expr_nodes_spec.rb +8 -6
- data/spec/skeem/skm_compound_datum_spec.rb +12 -10
- data/spec/skeem/skm_element_spec.rb +7 -5
- data/spec/skeem/skm_empty_list_spec.rb +7 -5
- data/spec/skeem/skm_frame_spec.rb +5 -4
- data/spec/skeem/skm_pair_spec.rb +9 -8
- data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
- data/spec/skeem/skm_simple_datum_spec.rb +24 -22
- data/spec/skeem/skm_unary_expression_spec.rb +11 -9
- data/spec/skeem/tokenizer_spec.rb +54 -43
- data/spec/skeem_spec.rb +2 -0
- data/spec/spec_helper.rb +15 -10
- metadata +13 -9
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative 'skm_expression'
         | 
| 2 4 |  | 
| 3 5 | 
             
            module Skeem
         | 
| @@ -29,7 +31,7 @@ module Skeem | |
| 29 31 | 
             
                  super(nil, aDatum)
         | 
| 30 32 | 
             
                end
         | 
| 31 33 |  | 
| 32 | 
            -
                def evaluate( | 
| 34 | 
            +
                def evaluate(_runtime)
         | 
| 33 35 | 
             
                  datum
         | 
| 34 36 | 
             
                end
         | 
| 35 37 |  | 
| @@ -47,7 +49,6 @@ module Skeem | |
| 47 49 | 
             
                def inspect_specific
         | 
| 48 50 | 
             
                  datum.inspect
         | 
| 49 51 | 
             
                end
         | 
| 50 | 
            -
             | 
| 51 52 | 
             
              end # class
         | 
| 52 53 |  | 
| 53 54 | 
             
              class SkmQuasiquotation < SkmQuotation
         | 
| @@ -60,7 +61,6 @@ module Skeem | |
| 60 61 | 
             
                def quasiquote(aRuntime)
         | 
| 61 62 | 
             
                  child.quasiquote(aRuntime)
         | 
| 62 63 | 
             
                end
         | 
| 63 | 
            -
             | 
| 64 64 | 
             
              end # class
         | 
| 65 65 |  | 
| 66 66 | 
             
              class SkmUnquotation < SkmUnaryExpression
         | 
| @@ -76,8 +76,7 @@ module Skeem | |
| 76 76 | 
             
                end
         | 
| 77 77 |  | 
| 78 78 | 
             
                def quasiquote(aRuntime)
         | 
| 79 | 
            -
                   | 
| 80 | 
            -
                  result
         | 
| 79 | 
            +
                  evaluate(aRuntime)
         | 
| 81 80 | 
             
                end
         | 
| 82 81 |  | 
| 83 82 | 
             
                protected
         | 
| @@ -87,7 +86,7 @@ module Skeem | |
| 87 86 | 
             
                end
         | 
| 88 87 | 
             
              end # class
         | 
| 89 88 |  | 
| 90 | 
            -
              class SkmVariableReference | 
| 89 | 
            +
              class SkmVariableReference < SkmUnaryExpression
         | 
| 91 90 | 
             
                alias variable child
         | 
| 92 91 |  | 
| 93 92 | 
             
                def eqv?(other)
         | 
| @@ -100,13 +99,13 @@ module Skeem | |
| 100 99 | 
             
                  aRuntime.evaluate(var_key)
         | 
| 101 100 | 
             
                end
         | 
| 102 101 |  | 
| 103 | 
            -
                def quasiquote( | 
| 102 | 
            +
                def quasiquote(_runtime)
         | 
| 104 103 | 
             
                  self
         | 
| 105 104 | 
             
                end
         | 
| 106 105 |  | 
| 107 106 | 
             
                # Confusing!
         | 
| 108 107 | 
             
                # Value, here, means the value of the identifier (the variable's name).
         | 
| 109 | 
            -
                def value | 
| 108 | 
            +
                def value
         | 
| 110 109 | 
             
                  variable.value
         | 
| 111 110 | 
             
                end
         | 
| 112 111 | 
             
              end # class
         | 
| @@ -115,7 +114,10 @@ module Skeem | |
| 115 114 | 
             
              class SkmBindingBlock < SkmUnaryExpression
         | 
| 116 115 | 
             
                alias body child
         | 
| 117 116 |  | 
| 117 | 
            +
                # @return [Symbol] One of: :let, :let_star
         | 
| 118 118 | 
             
                attr_reader :kind
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                # @return [Array<SkmBinding>]
         | 
| 119 121 | 
             
                attr_reader :bindings
         | 
| 120 122 |  | 
| 121 123 | 
             
                def initialize(theKind, theBindings, aBody)
         | 
| @@ -126,14 +128,15 @@ module Skeem | |
| 126 128 |  | 
| 127 129 | 
             
                def evaluate(aRuntime)
         | 
| 128 130 | 
             
                  aRuntime.push(SkmFrame.new(aRuntime.environment))
         | 
| 129 | 
            -
                   | 
| 131 | 
            +
                  case kind
         | 
| 132 | 
            +
                  when :let
         | 
| 130 133 | 
             
                    locals = bindings.map do |bnd|
         | 
| 131 134 | 
             
                      SkmBinding.new(bnd.variable, bnd.value.evaluate(aRuntime))
         | 
| 132 135 | 
             
                    end
         | 
| 133 136 | 
             
                    locals.each do |bnd|
         | 
| 134 137 | 
             
                      aRuntime.add_binding(bnd.variable.evaluate(aRuntime), bnd.value)
         | 
| 135 138 | 
             
                    end
         | 
| 136 | 
            -
                   | 
| 139 | 
            +
                  when :let_star
         | 
| 137 140 | 
             
                    bindings.each do |bnd|
         | 
| 138 141 | 
             
                      val = bnd.value.evaluate(aRuntime)
         | 
| 139 142 | 
             
                      aRuntime.add_binding(bnd.variable.evaluate(aRuntime), val)
         | 
| @@ -155,7 +158,6 @@ module Skeem | |
| 155 158 | 
             
                  # $stderr.puts "Result SkmBindingBlock#evaluate: " + result.inspect
         | 
| 156 159 | 
             
                  result
         | 
| 157 160 | 
             
                end
         | 
| 158 | 
            -
             | 
| 159 161 | 
             
              end # class
         | 
| 160 162 |  | 
| 161 163 | 
             
              # Sequencing construct
         | 
| @@ -187,18 +189,16 @@ module Skeem | |
| 187 189 | 
             
                def eval_pair(aRuntime)
         | 
| 188 190 | 
             
                  result = nil
         | 
| 189 191 | 
             
                  sequence.to_a.each do |cmd|
         | 
| 190 | 
            -
                     | 
| 191 | 
            -
                       | 
| 192 | 
            -
             | 
| 193 | 
            -
                       | 
| 194 | 
            -
                        result = cmd.evaluate(aRuntime)
         | 
| 195 | 
            -
                      end
         | 
| 196 | 
            -
                    rescue NoMethodError => exc
         | 
| 197 | 
            -
                      $stderr.puts self.inspect
         | 
| 198 | 
            -
                      $stderr.puts sequence.inspect
         | 
| 199 | 
            -
                      $stderr.puts cmd.inspect
         | 
| 200 | 
            -
                      raise exc
         | 
| 192 | 
            +
                    if cmd.kind_of?(SkmLambda)
         | 
| 193 | 
            +
                      result = cmd.dup_cond(aRuntime)
         | 
| 194 | 
            +
                    else
         | 
| 195 | 
            +
                      result = cmd.evaluate(aRuntime)
         | 
| 201 196 | 
             
                    end
         | 
| 197 | 
            +
                  rescue NoMethodError => e
         | 
| 198 | 
            +
                    $stderr.puts inspect
         | 
| 199 | 
            +
                    $stderr.puts sequence.inspect
         | 
| 200 | 
            +
                    $stderr.puts cmd.inspect
         | 
| 201 | 
            +
                    raise e
         | 
| 202 202 | 
             
                  end
         | 
| 203 203 |  | 
| 204 204 | 
             
                  result
         | 
| @@ -216,27 +216,24 @@ module Skeem | |
| 216 216 |  | 
| 217 217 | 
             
                  if sequence[:sequence].kind_of?(SkmPair)
         | 
| 218 218 | 
             
                    sequence[:sequence].to_a.each do |cmd|
         | 
| 219 | 
            -
                       | 
| 220 | 
            -
                         | 
| 221 | 
            -
             | 
| 222 | 
            -
                         | 
| 223 | 
            -
                          result = cmd.evaluate(aRuntime)
         | 
| 224 | 
            -
                        end
         | 
| 225 | 
            -
                      rescue NoMethodError => exc
         | 
| 226 | 
            -
                        $stderr.puts self.inspect
         | 
| 227 | 
            -
                        $stderr.puts sequence[:sequence].inspect
         | 
| 228 | 
            -
                        $stderr.puts cmd.inspect
         | 
| 229 | 
            -
                        raise exc
         | 
| 219 | 
            +
                      if cmd.kind_of?(SkmLambda)
         | 
| 220 | 
            +
                        result = cmd.dup_cond(aRuntime)
         | 
| 221 | 
            +
                      else
         | 
| 222 | 
            +
                        result = cmd.evaluate(aRuntime)
         | 
| 230 223 | 
             
                      end
         | 
| 224 | 
            +
                    rescue NoMethodError => e
         | 
| 225 | 
            +
                      $stderr.puts inspect
         | 
| 226 | 
            +
                      $stderr.puts sequence[:sequence].inspect
         | 
| 227 | 
            +
                      $stderr.puts cmd.inspect
         | 
| 228 | 
            +
                      raise e
         | 
| 231 229 | 
             
                    end
         | 
| 232 | 
            -
                   | 
| 230 | 
            +
                  else
         | 
| 233 231 | 
             
                    result = sequence.evaluate(aRuntime)
         | 
| 234 232 | 
             
                  end
         | 
| 235 233 |  | 
| 236 234 | 
             
                  aRuntime.pop
         | 
| 237 | 
            -
             | 
| 235 | 
            +
             | 
| 238 236 | 
             
                  result
         | 
| 239 237 | 
             
                end
         | 
| 240 238 | 
             
              end # class
         | 
| 241 | 
            -
             | 
| 242 | 
            -
            end # module
         | 
| 239 | 
            +
            end # module
         | 
    
        data/lib/skeem/tokenizer.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            # File: tokenizer.rb
         | 
| 2 4 | 
             
            # Tokenizer for Skeem language (a small subset of Scheme)
         | 
| 3 5 | 
             
            require 'strscan'
         | 
| @@ -14,8 +16,13 @@ module Skeem | |
| 14 16 | 
             
              # Delimiters: parentheses '(',  ')'
         | 
| 15 17 | 
             
              # Separators: comma
         | 
| 16 18 | 
             
              class Tokenizer
         | 
| 19 | 
            +
                # @return [StringScanner]
         | 
| 17 20 | 
             
                attr_reader(:scanner)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                # @return [Integer] Current line number
         | 
| 18 23 | 
             
                attr_reader(:lineno)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                # @return [Integer] Offset of start of current line
         | 
| 19 26 | 
             
                attr_reader(:line_start)
         | 
| 20 27 |  | 
| 21 28 | 
             
                @@lexeme2name = {
         | 
| @@ -25,9 +32,11 @@ module Skeem | |
| 25 32 | 
             
                  '(' => 'LPAREN',
         | 
| 26 33 | 
             
                  ')' => 'RPAREN',
         | 
| 27 34 | 
             
                  '.' => 'PERIOD',
         | 
| 35 | 
            +
                  '...' => 'ELLIPSIS',
         | 
| 28 36 | 
             
                  ',' => 'COMMA',
         | 
| 29 37 | 
             
                  ',@' =>  'COMMA_AT_SIGN',
         | 
| 30 | 
            -
                  '#(' => 'VECTOR_BEGIN'
         | 
| 38 | 
            +
                  '#(' => 'VECTOR_BEGIN',
         | 
| 39 | 
            +
                  '_' => 'UNDERSCORE'
         | 
| 31 40 | 
             
                }.freeze
         | 
| 32 41 |  | 
| 33 42 | 
             
                # Here are all the implemented Scheme keywords (in uppercase)
         | 
| @@ -35,18 +44,21 @@ module Skeem | |
| 35 44 | 
             
                  BEGIN
         | 
| 36 45 | 
             
                  COND
         | 
| 37 46 | 
             
                  DEFINE
         | 
| 47 | 
            +
                  DEFINE-SYNTAX
         | 
| 38 48 | 
             
                  DO
         | 
| 39 49 | 
             
                  ELSE
         | 
| 40 50 | 
             
                  IF
         | 
| 51 | 
            +
                  INCLUDE
         | 
| 41 52 | 
             
                  LAMBDA
         | 
| 42 53 | 
             
                  LET
         | 
| 43 54 | 
             
                  LET*
         | 
| 44 55 | 
             
                  QUASIQUOTE
         | 
| 45 56 | 
             
                  QUOTE
         | 
| 46 57 | 
             
                  SET!
         | 
| 58 | 
            +
                  SYNTAX-RULES
         | 
| 47 59 | 
             
                  UNQUOTE
         | 
| 48 60 | 
             
                  UNQUOTE-SPLICING
         | 
| 49 | 
            -
                ].map { |x| [x, x] } | 
| 61 | 
            +
                ].map { |x| [x, x.sub(/\*$/, '_STAR')] }.to_h
         | 
| 50 62 |  | 
| 51 63 | 
             
                class ScanError < StandardError; end
         | 
| 52 64 |  | 
| @@ -57,7 +69,6 @@ module Skeem | |
| 57 69 | 
             
                  reinitialize(source)
         | 
| 58 70 | 
             
                end
         | 
| 59 71 |  | 
| 60 | 
            -
             | 
| 61 72 | 
             
                # @param source [String] Skeem text to tokenize.
         | 
| 62 73 | 
             
                def reinitialize(source)
         | 
| 63 74 | 
             
                  @scanner.string = source
         | 
| @@ -88,9 +99,9 @@ module Skeem | |
| 88 99 | 
             
                  if "()'`".include? curr_ch
         | 
| 89 100 | 
             
                    # Delimiters, separators => single character token
         | 
| 90 101 | 
             
                    token = build_token(@@lexeme2name[curr_ch], scanner.getch)
         | 
| 91 | 
            -
                  elsif (lexeme = scanner.scan(/( | 
| 92 | 
            -
                    token = build_token( | 
| 93 | 
            -
                  elsif (lexeme = scanner.scan(/(?:,@?)|(?:=>)/))
         | 
| 102 | 
            +
                  elsif (lexeme = scanner.scan(/(?:\.|_)(?=\s|\()/)) # Single char occurring alone
         | 
| 103 | 
            +
                    token = build_token(@@lexeme2name[curr_ch], scanner.getch)
         | 
| 104 | 
            +
                  elsif (lexeme = scanner.scan(/(?:,@?)|(?:=>)|(?:\.\.\.)/))
         | 
| 94 105 | 
             
                    token = build_token(@@lexeme2name[lexeme], lexeme)
         | 
| 95 106 | 
             
                  elsif (token = recognize_char_token)
         | 
| 96 107 | 
             
                    # Do nothing
         | 
| @@ -99,21 +110,21 @@ module Skeem | |
| 99 110 | 
             
                  elsif (lexeme = scanner.scan(/(?:#[dD])?[+-]?[0-9]+(?:.0+)?(?=\s|[|()";]|$)/))
         | 
| 100 111 | 
             
                    token = build_token('INTEGER', lexeme) # Decimal radix
         | 
| 101 112 | 
             
                  elsif (lexeme = scanner.scan(/#[xX][+-]?[0-9a-fA-F]+(?=\s|[|()";]|$)/))
         | 
| 102 | 
            -
                    token = build_token('INTEGER', lexeme) # Hexadecimal radix | 
| 113 | 
            +
                    token = build_token('INTEGER', lexeme) # Hexadecimal radix
         | 
| 103 114 | 
             
                  elsif (lexeme = scanner.scan(/[+-]?[0-9]+(?:\.[0-9]*)?(?:(?:e|E)[+-]?[0-9]+)?/))
         | 
| 104 115 | 
             
                    # Order dependency: must be tested after INTEGER case
         | 
| 105 116 | 
             
                    token = build_token('REAL', lexeme)
         | 
| 106 | 
            -
                  elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[ | 
| 107 | 
            -
                    token = cardinal_token(lexeme) | 
| 117 | 
            +
                  elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\(tfeiodx]|(?:\d+[=#]))/))
         | 
| 118 | 
            +
                    token = cardinal_token(lexeme)
         | 
| 108 119 | 
             
                  elsif (lexeme = scanner.scan(/"(?:\\"|[^"])*"/)) # Double quotes literal?
         | 
| 109 120 | 
             
                    token = build_token('STRING_LIT', lexeme)
         | 
| 110 121 | 
             
                  elsif (lexeme = scanner.scan(/[a-zA-Z!$%&*\/:<=>?@^_~][a-zA-Z0-9!$%&*+-.\/:<=>?@^_~+-]*/))
         | 
| 111 122 | 
             
                    keyw = @@keywords[lexeme.upcase]
         | 
| 112 | 
            -
                    tok_type = keyw  | 
| 123 | 
            +
                    tok_type = keyw || 'IDENTIFIER'
         | 
| 113 124 | 
             
                    token = build_token(tok_type, lexeme)
         | 
| 114 125 | 
             
                  elsif (lexeme = scanner.scan(/\|(?:[^|])*\|/)) # Vertical bar delimited
         | 
| 115 126 | 
             
                    token = build_token('IDENTIFIER', lexeme)
         | 
| 116 | 
            -
                  elsif (lexeme = scanner.scan(/([ | 
| 127 | 
            +
                  elsif (lexeme = scanner.scan(/([+\-])((?=\s|[|()";])|$)/))
         | 
| 117 128 | 
             
                    #  # R7RS peculiar identifiers case 1: isolated plus and minus as identifiers
         | 
| 118 129 | 
             
                    token = build_token('IDENTIFIER', lexeme)
         | 
| 119 130 | 
             
                  elsif (lexeme = scanner.scan(/[+-][a-zA-Z!$%&*\/:<=>?@^_~+-@][a-zA-Z0-9!$%&*+-.\/:<=>?@^_~+-]*/))
         | 
| @@ -151,17 +162,16 @@ other literal data (section 2.4). | |
| 151 162 | 
             
                  return token
         | 
| 152 163 | 
             
                end
         | 
| 153 164 |  | 
| 154 | 
            -
                def recognize_char_token | 
| 165 | 
            +
                def recognize_char_token
         | 
| 155 166 | 
             
                  token = nil
         | 
| 156 | 
            -
                  if lexeme = scanner.scan(/#\\/)
         | 
| 157 | 
            -
                    if lexeme = scanner.scan(/(?:alarm|backspace|delete|escape|newline|null|return|space|tab)/)
         | 
| 167 | 
            +
                  if (lexeme = scanner.scan(/#\\/))
         | 
| 168 | 
            +
                    if (lexeme = scanner.scan(/(?:alarm|backspace|delete|escape|newline|null|return|space|tab)/))
         | 
| 158 169 | 
             
                      token = build_token('CHAR', lexeme, :name)
         | 
| 159 | 
            -
                    elsif lexeme = scanner.scan(/[ | 
| 160 | 
            -
                      token = build_token('CHAR', lexeme, :escaped)
         | 
| 161 | 
            -
                    elsif lexeme = scanner.scan(/x[0-9a-fA-F]+/)
         | 
| 170 | 
            +
                    elsif (lexeme = scanner.scan(/x[0-9a-fA-F]+/))
         | 
| 162 171 | 
             
                      token = build_token('CHAR', lexeme, :hex_value)
         | 
| 163 | 
            -
                     | 
| 164 | 
            -
                       | 
| 172 | 
            +
                    else
         | 
| 173 | 
            +
                      lexeme = scanner.getch
         | 
| 174 | 
            +
                      token = build_token('CHAR', lexeme, :escaped)
         | 
| 165 175 | 
             
                    end
         | 
| 166 176 | 
             
                  end
         | 
| 167 177 |  | 
| @@ -174,9 +184,9 @@ other literal data (section 2.4). | |
| 174 184 | 
             
                    col = scanner.pos - aLexeme.size - @line_start + 1
         | 
| 175 185 | 
             
                    pos = Rley::Lexical::Position.new(@lineno, col)
         | 
| 176 186 | 
             
                    token = Rley::Lexical::Token.new(value, symb, pos)
         | 
| 177 | 
            -
                  rescue StandardError =>  | 
| 187 | 
            +
                  rescue StandardError => e
         | 
| 178 188 | 
             
                    puts "Failing with '#{aSymbolName}' and '#{aLexeme}'"
         | 
| 179 | 
            -
                    raise  | 
| 189 | 
            +
                    raise e
         | 
| 180 190 | 
             
                  end
         | 
| 181 191 |  | 
| 182 192 | 
             
                  return token
         | 
| @@ -207,11 +217,11 @@ other literal data (section 2.4). | |
| 207 217 | 
             
                  return [value, symb]
         | 
| 208 218 | 
             
                end
         | 
| 209 219 |  | 
| 210 | 
            -
                def to_boolean(aLexeme,  | 
| 211 | 
            -
                   | 
| 220 | 
            +
                def to_boolean(aLexeme, _format)
         | 
| 221 | 
            +
                  (aLexeme =~ /^#t/) ? true : false
         | 
| 212 222 | 
             
                end
         | 
| 213 223 |  | 
| 214 | 
            -
                def to_integer(aLexeme,  | 
| 224 | 
            +
                def to_integer(aLexeme, _format)
         | 
| 215 225 | 
             
                  literal = aLexeme.downcase
         | 
| 216 226 | 
             
                  prefix_pattern = /^#[dx]/
         | 
| 217 227 | 
             
                  matching = literal.match(prefix_pattern)
         | 
| @@ -226,7 +236,7 @@ other literal data (section 2.4). | |
| 226 236 | 
             
                  else
         | 
| 227 237 | 
             
                    format = :default
         | 
| 228 238 | 
             
                  end
         | 
| 229 | 
            -
             | 
| 239 | 
            +
             | 
| 230 240 | 
             
                  case format
         | 
| 231 241 | 
             
                    when :default, :base10
         | 
| 232 242 | 
             
                      value = literal.to_i
         | 
| @@ -303,11 +313,11 @@ other literal data (section 2.4). | |
| 303 313 |  | 
| 304 314 | 
             
                  name2char[name]
         | 
| 305 315 | 
             
                end
         | 
| 306 | 
            -
             | 
| 316 | 
            +
             | 
| 307 317 | 
             
                def escaped_char(aLexeme)
         | 
| 308 318 | 
             
                  aLexeme.chr
         | 
| 309 319 | 
             
                end
         | 
| 310 | 
            -
             | 
| 320 | 
            +
             | 
| 311 321 | 
             
                def hex_value_char(aLexeme)
         | 
| 312 322 | 
             
                  hex_literal = aLexeme.sub(/^x/, '')
         | 
| 313 323 | 
             
                  hex_value = hex_literal.to_i(16)
         | 
| @@ -338,15 +348,14 @@ other literal data (section 2.4). | |
| 338 348 | 
             
                      skip_block_comment
         | 
| 339 349 | 
             
                      next
         | 
| 340 350 | 
             
                    end
         | 
| 341 | 
            -
                    break unless ws_found  | 
| 351 | 
            +
                    break unless ws_found || cmt_found
         | 
| 342 352 | 
             
                  end
         | 
| 343 353 |  | 
| 344 354 | 
             
                  curr_pos = scanner.pos
         | 
| 345 355 | 
             
                  return if curr_pos == pre_pos
         | 
| 346 356 | 
             
                end
         | 
| 347 357 |  | 
| 348 | 
            -
                def skip_block_comment | 
| 349 | 
            -
                  # require 'debug'
         | 
| 358 | 
            +
                def skip_block_comment
         | 
| 350 359 | 
             
                  scanner.skip(/#\|/)
         | 
| 351 360 | 
             
                  nesting_level = 1
         | 
| 352 361 | 
             
                  loop do
         | 
| @@ -354,6 +363,7 @@ other literal data (section 2.4). | |
| 354 363 | 
             
                    unless comment_part
         | 
| 355 364 | 
             
                      raise ScanError, "Unterminated '#| ... |#' comment on line #{lineno}"
         | 
| 356 365 | 
             
                    end
         | 
| 366 | 
            +
             | 
| 357 367 | 
             
                    case scanner.matched
         | 
| 358 368 | 
             
                      when /(?:(?:\r\n)|\r|\n)/
         | 
| 359 369 | 
             
                        next_line
         | 
    
        data/lib/skeem/version.rb
    CHANGED
    
    
    
        data/lib/skeem.rb
    CHANGED
    
    
    
        data/skeem.gemspec
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            lib = File.expand_path('../lib', __FILE__)
         | 
| 2 4 | 
             
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 3 5 | 
             
            require 'skeem/version'
         | 
| @@ -8,6 +10,7 @@ module PkgExtending | |
| 8 10 | 
             
                file_list = Dir[
         | 
| 9 11 | 
             
                  '.rubocop.yml',
         | 
| 10 12 | 
             
                  '.rspec',
         | 
| 13 | 
            +
                  '.travis.yml',
         | 
| 11 14 | 
             
                  '.yardopts',
         | 
| 12 15 | 
             
                  'appveyor.yml',
         | 
| 13 16 | 
             
                  'Gemfile',
         | 
| @@ -21,6 +24,8 @@ module PkgExtending | |
| 21 24 | 
             
                  'lib/**/*.rb',
         | 
| 22 25 | 
             
                  'lib/**/*.skm',
         | 
| 23 26 | 
             
                  'spec/**/*.rb',
         | 
| 27 | 
            +
                  'spec/**/*.skm',
         | 
| 28 | 
            +
                  'spec/**/*.yml'
         | 
| 24 29 | 
             
                ]
         | 
| 25 30 | 
             
                aPackage.files = file_list
         | 
| 26 31 | 
             
                aPackage.test_files = Dir['spec/**/*_spec.rb']
         | 
| @@ -49,6 +54,7 @@ DESCR | |
| 49 54 | 
             
            SUMMARY
         | 
| 50 55 | 
             
              spec.homepage      = 'https://github.com/famished-tiger/Skeem'
         | 
| 51 56 | 
             
              spec.license       = 'MIT'
         | 
| 57 | 
            +
              spec.required_ruby_version = '>= 2.5.0'
         | 
| 52 58 |  | 
| 53 59 | 
             
              spec.bindir = 'bin'
         | 
| 54 60 | 
             
              spec.executables << 'skeem'
         | 
| @@ -56,14 +62,10 @@ SUMMARY | |
| 56 62 | 
             
              PkgExtending.pkg_files(spec)
         | 
| 57 63 | 
             
              PkgExtending.pkg_documentation(spec)
         | 
| 58 64 | 
             
              # Runtime dependencies
         | 
| 59 | 
            -
              spec.add_dependency 'rley', '~> 0. | 
| 65 | 
            +
              spec.add_dependency 'rley', '~> 0.8.03'
         | 
| 60 66 |  | 
| 61 67 | 
             
              # Development dependencies
         | 
| 62 | 
            -
            if RUBY_VERSION <= '2.2' 
         | 
| 63 | 
            -
              spec.add_development_dependency 'bundler', '~> 1.16'
         | 
| 64 | 
            -
            else
         | 
| 65 68 | 
             
              spec.add_development_dependency 'bundler', '~> 2.0'
         | 
| 66 | 
            -
            end
         | 
| 67 69 | 
             
              spec.add_development_dependency 'rake', '~> 12.0'
         | 
| 68 70 | 
             
              spec.add_development_dependency 'rspec', '~> 3.0'
         | 
| 69 71 | 
             
            end
         | 
    
        data/spec/skeem/add4.skm
    ADDED
    
    
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require_relative '../spec_helper'
         | 
| 2 4 |  | 
| 3 5 |  | 
| @@ -35,15 +37,15 @@ module Skeem | |
| 35 37 | 
             
                    ['+456', 456]
         | 
| 36 38 | 
             
                  ]
         | 
| 37 39 | 
             
                end
         | 
| 38 | 
            -
             | 
| 40 | 
            +
             | 
| 39 41 | 
             
                let(:rational_tests) do
         | 
| 40 42 | 
             
                  [
         | 
| 41 | 
            -
                    [-Rational(2,3), -Rational(2, 3)],
         | 
| 43 | 
            +
                    [-Rational(2, 3), -Rational(2, 3)],
         | 
| 42 44 | 
             
                    [Rational(22, 7), Rational(22, 7)],
         | 
| 43 45 | 
             
                    ['-2/3', -Rational(2, 3)],
         | 
| 44 46 | 
             
                    ['+22/7', Rational(22, 7)]
         | 
| 45 47 | 
             
                  ]
         | 
| 46 | 
            -
                end | 
| 48 | 
            +
                end
         | 
| 47 49 |  | 
| 48 50 | 
             
                let(:real_tests) do
         | 
| 49 51 | 
             
                  [
         | 
| @@ -60,13 +62,13 @@ module Skeem | |
| 60 62 |  | 
| 61 63 | 
             
                let(:string_tests) do
         | 
| 62 64 | 
             
                  [
         | 
| 63 | 
            -
                    [ | 
| 65 | 
            +
                    %w[hello hello]
         | 
| 64 66 | 
             
                  ]
         | 
| 65 67 | 
             
                end
         | 
| 66 68 |  | 
| 67 69 | 
             
                let(:identifier_tests) do
         | 
| 68 70 | 
             
                  [
         | 
| 69 | 
            -
                    [ | 
| 71 | 
            +
                    %w[define define],
         | 
| 70 72 | 
             
                    [SkmString.create('positive?'), 'positive?']
         | 
| 71 73 | 
             
                  ]
         | 
| 72 74 | 
             
                end
         | 
| @@ -76,7 +78,7 @@ module Skeem | |
| 76 78 | 
             
                    ['#t', SkmBoolean.create(true)],
         | 
| 77 79 | 
             
                    [-1, SkmInteger.create(-1)],
         | 
| 78 80 | 
             
                    [1.41, 1.41],
         | 
| 79 | 
            -
                    [ | 
| 81 | 
            +
                    %w[foo foo]
         | 
| 80 82 | 
             
                  ]
         | 
| 81 83 | 
             
                end
         | 
| 82 84 |  | 
| @@ -92,12 +94,12 @@ module Skeem | |
| 92 94 | 
             
                      expect(subject.integer(literal)).to eq(predicted)
         | 
| 93 95 | 
             
                    end
         | 
| 94 96 | 
             
                  end
         | 
| 95 | 
            -
             | 
| 97 | 
            +
             | 
| 96 98 | 
             
                  it 'should convert rational literals' do
         | 
| 97 99 | 
             
                    rational_tests.each do |(literal, predicted)|
         | 
| 98 100 | 
             
                      expect(subject.rational(literal)).to eq(predicted)
         | 
| 99 101 | 
             
                    end
         | 
| 100 | 
            -
                  end | 
| 102 | 
            +
                  end
         | 
| 101 103 |  | 
| 102 104 | 
             
                  it 'should convert real number literals' do
         | 
| 103 105 | 
             
                    real_tests.each do |(literal, predicted)|
         | 
| @@ -178,12 +180,12 @@ module Skeem | |
| 178 180 | 
             
                      expect(subject.to_datum(literal)).to eq(predicted)
         | 
| 179 181 | 
             
                    end
         | 
| 180 182 | 
             
                  end
         | 
| 181 | 
            -
             | 
| 183 | 
            +
             | 
| 182 184 | 
             
                  it 'should recognize & convert rational literals' do
         | 
| 183 185 | 
             
                    rational_tests.each do |(literal, predicted)|
         | 
| 184 186 | 
             
                      expect(subject.to_datum(literal)).to eq(predicted)
         | 
| 185 187 | 
             
                    end
         | 
| 186 | 
            -
                  end | 
| 188 | 
            +
                  end
         | 
| 187 189 |  | 
| 188 190 | 
             
                  it 'should recognize & convert real number literals' do
         | 
| 189 191 | 
             
                    real_tests.each do |(literal, predicted)|
         | 
| @@ -219,6 +221,5 @@ module Skeem | |
| 219 221 | 
             
                  # $stderr.puts duplicate.inspect
         | 
| 220 222 | 
             
                  expect(duplicate.to_a).to eq([f, g])
         | 
| 221 223 | 
             
                end
         | 
| 222 | 
            -
             | 
| 223 224 | 
             
              end # describe
         | 
| 224 | 
            -
            end # module
         | 
| 225 | 
            +
            end # module
         |