about summary refs log tree commit diff stats
path: root/html/022div.cc.html
blob: 76938759c17446e502b180ec786fae291a3b0781 (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
<!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 - 022div.cc</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.LineNr { }
.SpecialChar { color: #d70000; }
.Comment { color: #005faf; }
.Delimiter { color: #c000c0; }
.Identifier { color: #af5f00; }
.Constant { color: #008787; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
-->
</style>

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

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  var lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/022div.cc'>https://github.com/akkartik/mu/blob/master/022div.cc</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="Comment">//: helper for division operations: sign-extend EAX into EDX</span>
<span id="L2" class="LineNr"> 2 </span>
<span id="L3" class="LineNr"> 3 </span><span class="Delimiter">:(before &quot;End Initialize Op Names&quot;)</span>
<span id="L4" class="LineNr"> 4 </span><a href='001help.cc.html#L235'>put_new</a><span class="Delimiter">(</span><span class="SpecialChar"><a href='010vm.cc.html#L355'>Name</a></span><span class="Delimiter">,</span> <span class="Constant">&quot;99&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;sign-extend <a href='010vm.cc.html#L10'>EAX</a> into <a href='010vm.cc.html#L12'>EDX</a> (cdq)&quot;</span><span class="Delimiter">);</span>
<span id="L5" class="LineNr"> 5 </span>
<span id="L6" class="LineNr"> 6 </span><span class="Delimiter">:(code)</span>
<span id="L7" class="LineNr"> 7 </span><span class="Normal">void</span> <a href='022div.cc.html#L7'>test_cdq</a><span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span id="L8" class="LineNr"> 8 </span>  <span class="SpecialChar"><a href='010vm.cc.html#L25'>Reg</a></span>[EAX]<span class="Delimiter">.</span>i = <span class="Constant">10</span><span class="Delimiter">;</span>
<span id="L9" class="LineNr"> 9 </span>  <a href='011run.cc.html#L82'>run</a><span class="Delimiter">(</span>
<span id="L10" class="LineNr">10 </span>      <span class="Constant">&quot;== code 0x1\n&quot;</span>
<span id="L11" class="LineNr">11 </span>      <span class="Constant">&quot;99\n&quot;</span>
<span id="L12" class="LineNr">12 </span>  <span class="Delimiter">);</span>
<span id="L13" class="LineNr">13 </span>  <a href='003trace.cc.html#L290'>CHECK_TRACE_CONTENTS</a><span class="Delimiter">(</span>
<span id="L14" class="LineNr">14 </span>      <span class="Constant">&quot;run: sign-extend <a href='010vm.cc.html#L10'>EAX</a> into EDX\n&quot;</span>
<span id="L15" class="LineNr">15 </span>      <span class="Constant">&quot;run: <a href='010vm.cc.html#L12'>EDX</a> is now 0x00000000\n&quot;</span>
<span id="L16" class="LineNr">16 </span>  <span class="Delimiter">);</span>
<span id="L17" class="LineNr">17 </span><span class="Delimiter">}</span>
<span id="L18" class="LineNr">18 </span>
<span id="L19" class="LineNr">19 </span><span class="Delimiter">:(before &quot;End Single-Byte Opcodes&quot;)</span>
<span id="L20" class="LineNr">20 </span><span class="Normal">case</span> <span class="Constant">0x99</span>: <span class="Delimiter">{</span>  <span class="Comment">// sign-extend EAX into EDX</span>
<span id="L21" class="LineNr">21 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="SpecialChar">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;sign-extend <a href='010vm.cc.html#L10'>EAX</a> into EDX&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L22" class="LineNr">22 </span>  <span class="SpecialChar"><a href='010vm.cc.html#L25'>Reg</a></span>[EDX]<span class="Delimiter">.</span>i = <span class="Delimiter">(</span><span class="SpecialChar"><a href='010vm.cc.html#L25'>Reg</a></span>[EAX]<span class="Delimiter">.</span>i &lt; <span class="Constant">0</span><span class="Delimiter">)</span> ? -<span class="Constant">1</span> : <span class="Constant">0</span><span class="Delimiter">;</span>
<span id="L23" class="LineNr">23 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="SpecialChar">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;EDX is now 0x&quot;</span> &lt;&lt; <a href='010vm.cc.html#L408'>HEXWORD</a> &lt;&lt; <span class="SpecialChar"><a href='010vm.cc.html#L25'>Reg</a></span>[EDX]<span class="Delimiter">.</span>u &lt;&lt; end<span class="Delimiter">();</span>
<span id="L24" class="LineNr">24 </span>  <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L25" class="LineNr">25 </span><span class="Delimiter">}</span>
<span id="L26" class="LineNr">26 </span>
<span id="L27" class="LineNr">27 </span><span class="Delimiter">:(code)</span>
<span id="L28" class="LineNr">28 </span><span class="Normal">void</span> <a href='022div.cc.html#L28'>test_cdq_negative</a><span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span id="L29" class="LineNr">29 </span>  <span class="SpecialChar"><a href='010vm.cc.html#L25'>Reg</a></span>[EAX]<span class="Delimiter">.</span>i = -<span class="Constant">10</span><span class="Delimiter">;</span>
<span id="L30" class="LineNr">30 </span>  <a href='011run.cc.html#L82'>run</a><span class="Delimiter">(</span>
<span id="L31" class="LineNr">31 </span>      <span class="Constant">&quot;== code 0x1\n&quot;</span>
<span id="L32" class="LineNr">32 </span>      <span class="Constant">&quot;99\n&quot;</span>
<span id="L33" class="LineNr">33 </span>  <span class="Delimiter">);</span>
<span id="L34" class="LineNr">34 </span>  <a href='003trace.cc.html#L290'>CHECK_TRACE_CONTENTS</a><span class="Delimiter">(</span>
<span id="L35" class="LineNr">35 </span>      <span class="Constant">&quot;run: sign-extend <a href='010vm.cc.html#L10'>EAX</a> into EDX\n&quot;</span>
<span id="L36" class="LineNr">36 </span>      <span class="Constant">&quot;run: <a href='010vm.cc.html#L12'>EDX</a> is now 0xffffffff\n&quot;</span>
<span id="L37" class="LineNr">37 </span>  <span class="Delimiter">);</span>
<span id="L38" class="LineNr">38 </span><span class="Delimiter">}</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->
pan class="nv">null x2:&:cell <- first y 10:bool/raw <- equal x, x2 11:&:cell/raw <- rest y memory-should-contain [ 10 <- 1 # first is correct 11 <- 0 # rest is nil ] ] ## convert lambda text to a tree of cells def parse in:text -> out:&:cell [ local-scope load-inputs s:&:stream:char <- new-stream in out, s <- parse s trace 2, [app/parse], out ] def parse in:&:stream:char -> out:&:cell, in:&:stream:char [ local-scope load-inputs # skip whitespace in <- skip-whitespace in c:char, eof?:bool <- peek in return-if eof?, null pair?:bool <- equal c, 40/open-paren { break-if pair? # atom buf:&:buffer:char <- new-buffer 30 { done?:bool <- end-of-stream? in break-if done? # stop before close paren or space c:char <- peek in done? <- equal c, 41/close-paren break-if done? done? <- space? c break-if done? c <- read in buf <- append buf, c loop } s:text <- buffer-to-array buf out <- new-atom s } { break-unless pair? # pair read in # skip the open-paren out <- new cell:type # start out with nil # read in first element of pair { end?:bool <- end-of-stream? in not-end?:bool <- not end? assert not-end?, [unbalanced '(' in expression] c <- peek in close-paren?:bool <- equal c, 41/close-paren break-if close-paren? first:&:cell, in <- parse in *out <- merge 1/pair, first, null } # read in any remaining elements curr:&:cell <- copy out { in <- skip-whitespace in end?:bool <- end-of-stream? in not-end?:bool <- not end? assert not-end?, [unbalanced '(' in expression] # termination check: ')' c <- peek in { close-paren?:bool <- equal c, 41/close-paren break-unless close-paren? read in # skip ')' break +end-pair } # still here? read next element of pair next:&:cell, in <- parse in is-dot?:bool <- atom-match? next, [.] { break-if is-dot? next-curr:&:cell <- new-pair next, null curr <- set-rest curr, next-curr curr <- rest curr } { break-unless is-dot? # deal with dotted pair in <- skip-whitespace in c <- peek in not-close-paren?:bool <- not-equal c, 41/close-paren assert not-close-paren?, [')' cannot immediately follow '.'] final:&:cell <- parse in curr <- set-rest curr, final # we're not gonna update curr, so better make sure the next iteration # is going to end the pair in <- skip-whitespace in c <- peek in close-paren?:bool <- equal c, 41/close-paren assert close-paren?, ['.' must be followed by exactly one expression before ')'] } loop } +end-pair } ] def skip-whitespace in:&:stream:char -> in:&:stream:char [ local-scope load-inputs { done?:bool <- end-of-stream? in return-if done?, null c:char <- peek in space?:bool <- space? c break-unless space? read in # skip loop } ] def to-text x:&:cell -> out:text [ local-scope load-inputs buf:&:buffer:char <- new-buffer 30 buf <- to-buffer x, buf out <- buffer-to-array buf ] def to-buffer x:&:cell, buf:&:buffer:char -> buf:&:buffer:char [ local-scope load-inputs # base case: empty cell { break-if x buf <- append buf, [<>] return } # base case: atom { s:text, atom?:bool <- maybe-convert *x, atom:variant break-unless atom? buf <- append buf, s return } # recursive case: pair buf <- append buf, [< ] first:&:cell <- first x buf <- to-buffer first, buf buf <- append buf, [ | ] rest:&:cell <- rest x buf <- to-buffer rest, buf buf <- append buf, [ >] ] scenario parse-single-letter-atom [ local-scope s:text <- new [a] x:&:cell <- parse s s2:text, 10:bool/raw <- maybe-convert *x, atom:variant 11:@:char/raw <- copy *s2 memory-should-contain [ 10 <- 1 # parse result is an atom 11:array:character <- [a] ] ] scenario parse-atom [ local-scope s:text <- new [abc] x:&:cell <- parse s s2:text, 10:bool/raw <- maybe-convert *x, atom:variant 11:@:char/raw <- copy *s2 memory-should-contain [ 10 <- 1 # parse result is an atom 11:array:character <- [abc] ] ] scenario parse-list-of-two-atoms [ local-scope s:text <- new [(abc def)] x:&:cell <- parse s trace-should-contain [ app/parse: < abc | < def | <> > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant 12:bool/raw <- is-pair? x2 x3:&:cell <- first x2 s2:text, 13:bool/raw <- maybe-convert *x3, atom:variant 14:&:cell/raw <- rest x2 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is a pair 13 <- 1 # result.rest.first is an atom 14 <- 0 # result.rest.rest is nil 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest.first ] ] scenario parse-list-with-extra-spaces [ local-scope s:text <- new [ ( abc def ) ] # extra spaces x:&:cell <- parse s trace-should-contain [ app/parse: < abc | < def | <> > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant 12:bool/raw <- is-pair? x2 x3:&:cell <- first x2 s2:text, 13:bool/raw <- maybe-convert *x3, atom:variant 14:&:cell/raw <- rest x2 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is a pair 13 <- 1 # result.rest.first is an atom 14 <- 0 # result.rest.rest is nil 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest.first ] ] scenario parse-list-of-more-than-two-atoms [ local-scope s:text <- new [(abc def ghi)] x:&:cell <- parse s trace-should-contain [ app/parse: < abc | < def | < ghi | <> > > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant 12:bool/raw <- is-pair? x2 x3:&:cell <- first x2 s2:text, 13:bool/raw <- maybe-convert *x3, atom:variant x4:&:cell <- rest x2 14:bool/raw <- is-pair? x4 x5:&:cell <- first x4 s3:text, 15:bool/raw <- maybe-convert *x5, atom:variant 16:&:cell/raw <- rest x4 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 40:@:char/raw <- copy *s3 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is a pair 13 <- 1 # result.rest.first is an atom 14 <- 1 # result.rest.rest is a pair 15 <- 1 # result.rest.rest.first is an atom 16 <- 0 # result.rest.rest.rest is nil 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest.first 40:array:character <- [ghi] # result.rest.rest ] ] scenario parse-nested-list [ local-scope s:text <- new [((abc))] x:&:cell <- parse s trace-should-contain [ app/parse: < < abc | <> > | <> > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x 11:bool/raw <- is-pair? x x2:&:cell <- first x1 s1:text, 12:bool/raw <- maybe-convert *x2, atom:variant 13:&:cell/raw <- rest x1 14:&:cell/raw <- rest x 20:@:char/raw <- copy *s1 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is a pair 12 <- 1 # result.first.first is an atom 13 <- 0 # result.first.rest is nil 14 <- 0 # result.rest is nil 20:array:character <- [abc] # result.first.first ] ] scenario parse-nested-list-2 [ local-scope s:text <- new [((abc) def)] x:&:cell <- parse s trace-should-contain [ app/parse: < < abc | <> > | < def | <> > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x 11:bool/raw <- is-pair? x x2:&:cell <- first x1 s1:text, 12:bool/raw <- maybe-convert *x2, atom:variant 13:&:cell/raw <- rest x1 x3:&:cell <- rest x x4:&:cell <- first x3 s2:text, 14:bool/raw <- maybe-convert *x4, atom:variant 15:&:cell/raw <- rest x3 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is a pair 12 <- 1 # result.first.first is an atom 13 <- 0 # result.first.rest is nil 14 <- 1 # result.rest.first is an atom 15 <- 0 # result.rest.rest is nil 20:array:character <- [abc] # result.first.first 30:array:character <- [def] # result.rest.first ] ] # todo: uncomment these tests after we figure out how to continue tests after # assertion failures #? scenario parse-error [ #? local-scope #? s:text <- new [(] #? #? hide-errors #? x:&:cell <- parse s #? #? show-errors #? trace-should-contain [ #? error: unbalanced '(' in expression #? ] #? ] #? #? scenario parse-error-after-element [ #? local-scope #? s:text <- new [(abc] #? #? hide-errors #? x:&:cell <- parse s #? #? show-errors #? trace-should-contain [ #? error: unbalanced '(' in expression #? ] #? ] scenario parse-dotted-list-of-two-atoms [ local-scope s:text <- new [(abc . def)] x:&:cell <- parse s trace-should-contain [ app/parse: < abc | def > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant s2:text, 12:bool/raw <- maybe-convert *x2, atom:variant 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 memory-should-contain [ # parses to < abc | def > 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is an atom 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest ] ] scenario parse-dotted-list-of-more-than-two-atoms [ local-scope s:text <- new [(abc def . ghi)] x:&:cell <- parse s trace-should-contain [ app/parse: < abc | < def | ghi > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant 12:bool/raw <- is-pair? x2 x3:&:cell <- first x2 s2:text, 13:bool/raw <- maybe-convert *x3, atom:variant x4:&:cell <- rest x2 s3:text, 14:bool/raw <- maybe-convert *x4, atom:variant 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 40:@:char/raw <- copy *s3 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is a pair 13 <- 1 # result.rest.first is an atom 14 <- 1 # result.rest.rest is an atom 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest.first 40:array:character <- [ghi] # result.rest.rest ] ] ## convert tree of cells to Mu text def to-mu in:&:cell -> out:text [ local-scope load-inputs buf:&:buffer:char <- new-buffer 30 buf <- to-mu in, buf out <- buffer-to-array buf ] def to-mu in:&:cell, buf:&:buffer:char -> buf:&:buffer:char, result-name:text [ local-scope load-inputs # null cell? no change. # pair with all atoms? gensym a new variable # pair containing other pairs? recurse result-name <- copy null ]