about summary refs log tree commit diff stats
path: root/html/013literal_string.cc.html
blob: c81057d754d5f615f0a803463d65dcdf97b9036e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 013literal_string.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1em; }
.traceContains { color: #008000; }
.cSpecial { color: #008000; }
.Constant { color: #008080; }
.Comment { color: #8080ff; }
.Delimiter { color: #c000c0; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.CommentedCode { color: #6c6c6c; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment">//: For convenience, some instructions will take literal arrays of characters (strings).</span>
<span class="Comment">//:</span>
<span class="Comment">//: Instead of quotes, we'll use [] to delimit strings. That'll reduce the</span>
<span class="Comment">//: need for escaping since we can support nested brackets. And we can also</span>
<span class="Comment">//: imagine that 'recipe' might one day itself be defined in mu, doing its own</span>
<span class="Comment">//: parsing.</span>

<span class="Delimiter">:(scenarios load)</span>
<span class="Delimiter">:(scenario string_literal)</span>
recipe main [
  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc def]  <span class="Comment"># copy can't really take a string</span>
]
<span class="traceContains">+parse:   ingredient: {name: &quot;abc def&quot;, properties: [&quot;abc def&quot;: &quot;literal-string&quot;]}</span>

<span class="Delimiter">:(scenario string_literal_with_colons)</span>
recipe main [
  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc:def/ghi]
]
<span class="traceContains">+parse:   ingredient: {name: &quot;abc:def/ghi&quot;, properties: [&quot;abc:def/ghi&quot;: &quot;literal-string&quot;]}</span>

<span class="Delimiter">:(before &quot;End Mu Types Initialization&quot;)</span>
Type_number[<span class="Constant">&quot;literal-string&quot;</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>

<span class="Delimiter">:(after &quot;string next_word(istream&amp; in)&quot;)</span>
  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
    string result = slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
    skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
    skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
    <span class="Identifier">return</span> result<span class="Delimiter">;</span>
  <span class="Delimiter">}</span>

<span class="Delimiter">:(code)</span>
string slurp_quoted<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span>
  assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>
  ostringstream out<span class="Delimiter">;</span>
  int brace_depth = <span class="Constant">0</span><span class="Delimiter">;</span>
  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
    char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
<span class="CommentedCode">//?     cout &lt;&lt; (int)c &lt;&lt; &quot;: &quot; &lt;&lt; brace_depth &lt;&lt; '\n'; //? 2</span>
    if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
      out &lt;&lt; <span class="Delimiter">(</span>char<span class="Delimiter">)</span>in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
      <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
    out &lt;&lt; c<span class="Delimiter">;</span>
<span class="CommentedCode">//?     cout &lt;&lt; out.str() &lt;&lt; &quot;$\n&quot;; //? 1</span>
    if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> ++brace_depth<span class="Delimiter">;</span>
    if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> --brace_depth<span class="Delimiter">;</span>
    if <span class="Delimiter">(</span>brace_depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; brace_depth &gt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
    raise &lt;&lt; <span class="Constant">&quot;unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
    <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(after &quot;reagent::reagent(string s)&quot;)</span>
<span class="CommentedCode">//?   cout &lt;&lt; s.at(0) &lt;&lt; '\n'; //? 1</span>
  if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
    assert<span class="Delimiter">(</span>*s<span class="Delimiter">.</span>rbegin<span class="Delimiter">()</span> == <span class="Constant">']'</span><span class="Delimiter">);</span>
    <span class="Comment">// delete [] delimiters</span>
    s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span>
    s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">,</span> SIZE<span class="Delimiter">(</span>s<span class="Delimiter">));</span>
    name = s<span class="Delimiter">;</span>
    types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
    properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair&lt;string<span class="Delimiter">,</span> vector&lt;string&gt; &gt;<span class="Delimiter">(</span>name<span class="Delimiter">,</span> vector&lt;string&gt;<span class="Delimiter">()));</span>
    properties<span class="Delimiter">.</span>back<span class="Delimiter">().</span>second<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">&quot;literal-string&quot;</span><span class="Delimiter">);</span>
    <span class="Identifier">return</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>

<span class="Delimiter">:(scenario string_literal_nested)</span>
recipe main [
  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc [def]]
]
<span class="traceContains">+parse:   ingredient: {name: &quot;abc [def]&quot;, properties: [&quot;abc [def]&quot;: &quot;literal-string&quot;]}</span>

<span class="Delimiter">:(scenario string_literal_escaped)</span>
recipe main [
  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc \[def]
]
<span class="traceContains">+parse:   ingredient: {name: &quot;abc [def&quot;, properties: [&quot;abc [def&quot;: &quot;literal-string&quot;]}</span>

<span class="Delimiter">:(scenario string_literal_and_comment)</span>
recipe main [
  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc]  <span class="Comment"># comment</span>
]
<span class="traceContains">+parse: instruction: copy</span>
<span class="traceContains">+parse:   ingredient: {name: &quot;abc&quot;, properties: [&quot;abc&quot;: &quot;literal-string&quot;]}</span>
<span class="traceContains">+parse:   product: {name: &quot;1&quot;, properties: [&quot;1&quot;: &quot;address&quot;:&quot;array&quot;:&quot;character&quot;]}</span>
<span class="Comment"># no other ingredients</span>
$parse: <span class="Constant">3</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->