diff --git a/spec/zodiac/parser_spec.rb b/spec/zodiac/parser_spec.rb index 8e466c3..b16df33 100644 --- a/spec/zodiac/parser_spec.rb +++ b/spec/zodiac/parser_spec.rb @@ -30,4 +30,64 @@ end end end + + describe '.parse_literal' do + context 'when parse literal' do + context 'when number' do + it 'returns literal' do + parser = described_class.new('1') + + actual = parser.parse_literal + expected = { + kind: 'LITERAL', + value: 1 + } + + expect(actual).to eq(expected) + end + end + + context 'when decimal' do + it 'returns literal' do + parser = described_class.new('1.1') + + actual = parser.parse_literal + expected = { + kind: 'LITERAL', + value: 1.1 + } + + expect(actual).to eq(expected) + end + end + + context 'when string' do + it 'returns literal' do + parser = described_class.new('"hello"') + + actual = parser.parse_literal + expected = { + kind: 'LITERAL', + value: 'hello' + } + + expect(actual).to eq(expected) + end + end + + context 'when symbol' do + it 'returns literal' do + parser = described_class.new(':hello') + + actual = parser.parse_literal + expected = { + kind: 'LITERAL', + value: :hello + } + + expect(actual).to eq(expected) + end + end + end + end end diff --git a/src/zodiac/parser.rb b/src/zodiac/parser.rb index e19f3ec..d8d4064 100644 --- a/src/zodiac/parser.rb +++ b/src/zodiac/parser.rb @@ -18,8 +18,6 @@ def parse parse_program end - private - # PROGRAM : COMPSTMT def parse_program cmp_stmts = [] @@ -303,10 +301,23 @@ def parse_variable # | SYMBOL # | STRING # | STRING2 - # | HERE_DOC - # | REGEXP + # | HERE_DOC (TOD) + # | REGEXP (TODO) def parse_literal - { kind: 'LITERAL', value: nil } + cur_token = @tokens[@cur_index] + + if cur_token[:kind] == 'NUMBER' + { kind: 'LITERAL', value: cur_token[:value].include?('.') ? cur_token[:value].to_f : cur_token[:value].to_i } + elsif cur_token[:kind] == 'SYMBOL' && + cur_token[:value].start_with?(':') && + @tokens[@cur_index + 1][:kind] == 'IDENTIFIER' + + { kind: 'LITERAL', value: @tokens[@cur_index + 1][:value].to_sym } + elsif cur_token[:kind] == 'STRING' + { kind: 'LITERAL', value: cur_token[:value].gsub('"', '') } + else + raise ParseError, "Expected a literal. Received #{cur_token[:value]}" + end end end end