Class: Nydp::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/nydp/parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ns) ⇒ Parser

Returns a new instance of Parser.



5
6
7
# File 'lib/nydp/parser.rb', line 5

def initialize ns
  @ns = ns
end

Instance Attribute Details

#nsObject

Returns the value of attribute ns.



3
4
5
# File 'lib/nydp/parser.rb', line 3

def ns
  @ns
end

Instance Method Details

#close_delimiter_for(opener) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/nydp/parser.rb', line 76

def close_delimiter_for opener
  case opener
  when '"'
    /"/
  when /.*{$/
    /}/
  when /<<(.+)$/
    Regexp.new $1
  end
end

#expression(token_stream) ⇒ Object



105
106
107
# File 'lib/nydp/parser.rb', line 105

def expression token_stream
  next_form token_stream.next_token, token_stream
end

#next_form(token, token_stream) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/nydp/parser.rb', line 87

def next_form token, token_stream
  return nil if token.nil?
  case token.first
  when :string_open_delim
    string token_stream, token.last, close_delimiter_for(token.last)
  when :left_paren
    prefix_list token[1], read_list(token_stream, :right_paren)
  when :left_brace
    prefix_list token[1], read_list(token_stream, :right_brace, [sym("brace-list")])
  when :symbol
    parse_symbol token.last
  when :comment
    Pair.from_list [sym(:comment), token.last]
  else
    token.last
  end
end

#parse_symbol(txt) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/nydp/parser.rb', line 42

def parse_symbol txt
  case txt
  when /^[-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?$/
    txt.to_f
  when /^[-+]?[0-9]+$/
    txt.to_i
  when /^'(.+)$/
    Pair.from_list [sym(:quote), parse_symbol($1)]
  when /^`(.+)$/
    Pair.from_list [sym(:quasiquote), parse_symbol($1)]
  when /^,@(.+)$/
    Pair.from_list [sym(:"unquote-splicing"), parse_symbol($1)]
  when /^,(.+)$/
    Pair.from_list [sym(:unquote), parse_symbol($1)]
  else
    syms = txt.to_s.split /\./
    return split_sym syms, sym("dot-syntax") if syms.length > 1

    syms = txt.split /::/
    return split_sym syms, sym("colon-colon-syntax") if syms.length > 1

    syms = txt.split /:/
    return split_sym syms, sym("colon-syntax") if syms.length > 1

    syms = txt.split /->/
    return split_sym syms, sym("arrow-syntax") if syms.length > 1

    syms = txt.split(/=>/)
    return split_sym syms, sym("rocket-syntax") if syms.length > 1

    sym txt
  end
end

#prefix_list(prefix, list) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/nydp/parser.rb', line 22

def prefix_list prefix, list
  return list if prefix == ''
  case prefix
  when /^(.*)'$/
    prefix_list $1, Pair.from_list([sym(:quote), list])
  when /^(.*)`$/
    prefix_list $1, Pair.from_list([sym(:quasiquote), list])
  when /^(.*),$/
    prefix_list $1, Pair.from_list([sym(:unquote), list])
  when /^(.*),@$/
    prefix_list $1, Pair.from_list([sym(:"unquote-splicing"), list])
  else
    list
  end
end

#read_list(token_stream, termination_token, list = []) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/nydp/parser.rb', line 13

def read_list token_stream, termination_token, list=[]
  token = token_stream.next_token
  while token != nil && token.first != termination_token
    list << next_form(token, token_stream)
    token = token_stream.next_token
  end
  Pair.parse_list list
end

#split_sym(syms, pfx) ⇒ Object



38
39
40
# File 'lib/nydp/parser.rb', line 38

def split_sym syms, pfx
  return Pair.from_list [pfx] + syms.map { |s| parse_symbol s }
end

#string(token_stream, open_delimiter, close_delimiter) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/nydp/parser.rb', line 109

def string token_stream, open_delimiter, close_delimiter
  fragments = [sym(:"string-pieces")]
  string_token = token_stream.next_string_fragment(open_delimiter, close_delimiter)
  fragments << Nydp::StringAtom.new(string_token.string, string_token)
  while !(string_token.is_a? StringFragmentCloseToken)
    fragments << expression(token_stream)
    string_token = token_stream.next_string_fragment('', close_delimiter)
    fragments << Nydp::StringAtom.new(string_token.string, string_token)
  end

  if fragments.size == 2
    return fragments[1]
  else
    return Pair.from_list fragments
  end
end

#sym(name) ⇒ Object



9
10
11
# File 'lib/nydp/parser.rb', line 9

def sym name
  Nydp::Symbol.mk name.to_sym, ns
end