summary refs log tree commit diff stats
path: root/lib/pure/xmldomparser.nim
blob: fda46bac0ffcab17d34fa52807b091045710a283 (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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#
#
#            Nimrod's Runtime Library
#        (c) Copyright 2010 Dominik Picheta
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

import xmldom, os, streams, parsexml, strutils

## This module parses a XML Document into a XML DOM Document representation.

#XMLDom's Parser - Turns XML into a Document

type
  # Parsing errors
  EMismatchedTag* = object of EInvalidValue ## Raised when a tag is not properly closed
  EParserError* = object of EInvalidValue ## Raised when an unexpected XML Parser event occurs

  # For namespaces
  xmlnsAttr = tuple[name, value: string, ownerElement: PElement]

var nsList: seq[xmlnsAttr] = @[] # Used for storing namespaces

proc getNS(prefix: string): string =
  var defaultNS: seq[string] = @[]

  for key, value, tag in items(nsList):
    if ":" in key:
      if key.split(':')[1] == prefix:
        return value
        
    if key == "xmlns":
      defaultNS.add(value)
      
  # Don't return the default namespaces
  # in the loop, because then they would have a precedence
  # over normal namespaces
  if defaultNS.len() > 0:
    return defaultNS[0] # Return the first found default namespace
                        # if none are specified for this prefix
    
  return ""
    
proc parseText(x: var TXmlParser, doc: var PDocument): PText =
  result = doc.createTextNode(x.charData())

proc parseElement(x: var TXmlParser, doc: var PDocument): PElement =
  var n = doc.createElement("")

  while True:
    case x.kind()
    of xmlEof:
      break
    of xmlElementStart, xmlElementOpen:
      if n.tagName() != "":
        n.appendChild(parseElement(x, doc))
      else:
        n = doc.createElementNS("", x.elementName)
        
    of xmlElementEnd:
      if x.elementName == n.nodeName:
        # n.normalize() # Remove any whitespace etc.
        
        var ns: string
        if x.elementName.contains(':'):
          ns = getNS(x.elementName.split(':')[0])
        else:
          ns = getNS("")
        
        n.namespaceURI = ns
        
        # Remove any namespaces this element declared
        var count = 0 # Variable which keeps the index
                      # We need to edit it..
        for i in low(nsList)..len(nsList)-1:
          if nsList[count][2] == n:
            nsList.delete(count)
            dec(count)
          inc(count)

        return n
      else: #The wrong element is ended
        raise newException(EMismatchedTag, "Mismatched tag at line " & 
          $x.getLine() & " column " & $x.getColumn)
      
    of xmlCharData:
      n.appendChild(parseText(x, doc))
    of xmlAttribute:
      if x.attrKey == "xmlns" or x.attrKey.startsWith("xmlns:"):
        nsList.add((x.attrKey, x.attrValue, n))
        
      if x.attrKey.contains(':'):
        var ns = getNS(x.attrKey)
        n.setAttributeNS(ns, x.attrKey, x.attrValue)
      else:
        n.setAttribute(x.attrKey, x.attrValue)

    of xmlCData:
      n.appendChild(doc.createCDATASection(x.charData()))
    of xmlComment:
      n.appendChild(doc.createComment(x.charData()))
    of xmlPI:
      n.appendChild(doc.createProcessingInstruction(x.PIName(), x.PIRest()))
      
    of xmlWhitespace, xmlElementClose, xmlEntity, xmlSpecial:
      # Unused 'events'

    else:
      raise newException(EParserError, "Unexpected XML Parser event")
    x.next()

  raise newException(EMismatchedTag, 
    "Mismatched tag at line " & $x.getLine() & " column " & $x.getColumn)

proc loadXMLStream*(stream: PStream): PDocument =
  ## Loads and parses XML from a stream specified by ``stream``, and returns 
  ## a ``PDocument``

  var x: TXmlParser
  open(x, stream, nil, {reportComments})
  
  var XmlDoc: PDocument
  var DOM: PDOMImplementation = getDOM()
  
  while True:
    x.next()
    case x.kind()
    of xmlEof:
      break
    of xmlElementStart, xmlElementOpen:
      var el: PElement = parseElement(x, XmlDoc)
      XmlDoc = dom.createDocument(el)
    of xmlWhitespace, xmlElementClose, xmlEntity, xmlSpecial:
      # Unused 'events'
    else:
      raise newException(EParserError, "Unexpected XML Parser event")

  return XmlDoc

proc loadXML*(xml: string): PDocument =
  ## Loads and parses XML from a string specified by ``xml``, and returns 
  ## a ``PDocument``
  var s = newStringStream(xml)
  return loadXMLStream(s)
  
    
proc loadXMLFile*(path: string): PDocument =
  ## Loads and parses XML from a file specified by ``path``, and returns 
  ## a ``PDocument``
  
  var s = newFileStream(path, fmRead)
  if s == nil: raise newException(EIO, "Unable to read file " & path)
  return loadXMLStream(s)


when isMainModule:
  var xml = loadXMLFile(r"C:\Users\Dominik\Desktop\Code\Nimrod\xmldom\test.xml")
  #echo(xml.getElementsByTagName("m:test2")[0].namespaceURI)
  #echo(xml.getElementsByTagName("bla:test")[0].namespaceURI)
  #echo(xml.getElementsByTagName("test")[0].namespaceURI)
  for i in items(xml.getElementsByTagName("*")):
    if i.namespaceURI != nil:
      echo(i.nodeName, "=", i.namespaceURI)

    
  echo($xml)
t">span id="L13" class="LineNr"> 13 </span> <span class="subxComment"># push sentinel</span> <span id="L14" class="LineNr"> 14 </span> <span class="subxComment"># eax = abs(n)</span> <span id="L15" class="LineNr"> 15 </span> <span class="subxComment"># while true</span> <span id="L16" class="LineNr"> 16 </span> <span class="subxComment"># sign-extend eax into edx</span> <span id="L17" class="LineNr"> 17 </span> <span class="subxComment"># eax, edx = eax/10, eax%10</span> <span id="L18" class="LineNr"> 18 </span> <span class="subxComment"># edx += '0'</span> <span id="L19" class="LineNr"> 19 </span> <span class="subxComment"># push edx</span> <span id="L20" class="LineNr"> 20 </span> <span class="subxComment"># if (eax == 0) break</span> <span id="L21" class="LineNr"> 21 </span> <span class="subxComment"># if n &lt; 0</span> <span id="L22" class="LineNr"> 22 </span> <span class="subxComment"># push '-'</span> <span id="L23" class="LineNr"> 23 </span> <span class="subxComment"># w = out-&gt;write</span> <span id="L24" class="LineNr"> 24 </span> <span class="subxComment"># curr = &amp;out-&gt;data[out-&gt;write]</span> <span id="L25" class="LineNr"> 25 </span> <span class="subxComment"># max = &amp;out-&gt;data[out-&gt;size]</span> <span id="L26" class="LineNr"> 26 </span> <span class="subxComment"># while true</span> <span id="L27" class="LineNr"> 27 </span> <span class="subxComment"># pop into eax</span> <span id="L28" class="LineNr"> 28 </span> <span class="subxComment"># if (eax == sentinel) break</span> <span id="L29" class="LineNr"> 29 </span> <span class="subxComment"># if (curr &gt;= max) abort</span> <span id="L30" class="LineNr"> 30 </span> <span class="subxComment"># *curr = AL</span> <span id="L31" class="LineNr"> 31 </span> <span class="subxComment"># ++curr</span> <span id="L32" class="LineNr"> 32 </span> <span class="subxComment"># ++w</span> <span id="L33" class="LineNr"> 33 </span> <span class="subxComment"># out-&gt;write = w</span> <span id="L34" class="LineNr"> 34 </span> <span class="subxComment"># (based on K&amp;R itoa: <a href="https://en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa)">https://en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa)</a></span> <span id="L35" class="LineNr"> 35 </span> <span class="subxComment"># (this pseudocode contains registers because operations like division</span> <span id="L36" class="LineNr"> 36 </span> <span class="subxComment"># require specific registers in x86)</span> <span id="L37" class="LineNr"> 37 </span> <span class="subxComment">#</span> <span id="L38" class="LineNr"> 38 </span> <span class="subxS1Comment"># . prologue</span> <span id="L39" class="LineNr"> 39 </span> 55/push-ebp <span id="L40" class="LineNr"> 40 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L41" class="LineNr"> 41 </span> <span class="subxS1Comment"># . save registers</span> <span id="L42" class="LineNr"> 42 </span> 50/push-eax <span id="L43" class="LineNr"> 43 </span> 51/push-ecx <span id="L44" class="LineNr"> 44 </span> 52/push-edx <span id="L45" class="LineNr"> 45 </span> 53/push-ebx <span id="L46" class="LineNr"> 46 </span> 57/push-edi <span id="L47" class="LineNr"> 47 </span> <span class="subxComment"># const ten/ecx = 10</span> <span id="L48" class="LineNr"> 48 </span> b9/copy-to-ecx 0xa/imm32 <span id="L49" class="LineNr"> 49 </span> <span class="subxComment"># push sentinel</span> <span id="L50" class="LineNr"> 50 </span> 68/push 0/imm32/sentinel <span id="L51" class="LineNr"> 51 </span> <span class="subxComment"># var eax: int = abs(n)</span> <span id="L52" class="LineNr"> 52 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+12) to eax</span> <span id="L53" class="LineNr"> 53 </span> 3d/compare-eax-with 0/imm32 <span id="L54" class="LineNr"> 54 </span> 7d/jump-if-&gt;= $write-int32-decimal:read-loop/disp8 <span id="L55" class="LineNr"> 55 </span><span class="Constant">$write-int32-decimal:negative</span>: <span id="L56" class="LineNr"> 56 </span> f7 3/subop/negate 3/mod/direct 0/rm32/eax <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># negate eax</span> <span id="L57" class="LineNr"> 57 </span><span class="Constant">$write-int32-decimal:read-loop</span>: <span id="L58" class="LineNr"> 58 </span> <span class="subxComment"># eax, edx = eax / 10, eax % 10</span> <span id="L59" class="LineNr"> 59 </span> 99/sign-extend-eax-into-edx <span id="L60" class="LineNr"> 60 </span> f7 7/subop/idiv 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># divide edx:eax by ecx, storing quotient in eax and remainder in edx</span> <span id="L61" class="LineNr"> 61 </span> <span class="subxComment"># edx += '0'</span> <span id="L62" class="LineNr"> 62 </span> 81 0/subop/add 3/mod/direct 2/rm32/edx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0x30/imm32 <span class="subxComment"># add to edx</span> <span id="L63" class="LineNr"> 63 </span> <span class="subxComment"># push edx</span> <span id="L64" class="LineNr"> 64 </span> 52/push-edx <span id="L65" class="LineNr"> 65 </span> <span class="subxComment"># if (eax == 0) break</span> <span id="L66" class="LineNr"> 66 </span> 3d/compare-eax-and 0/imm32 <span id="L67" class="LineNr"> 67 </span> 7f/jump-if-&gt; $write-int32-decimal:read-loop/disp8 <span id="L68" class="LineNr"> 68 </span><span class="Constant">$write-int32-decimal:read-break</span>: <span id="L69" class="LineNr"> 69 </span> <span class="subxComment"># if (n &lt; 0) push('-')</span> <span id="L70" class="LineNr"> 70 </span> 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/disp8 0/imm32 <span class="subxComment"># compare *(ebp+12)</span> <span id="L71" class="LineNr"> 71 </span> 7d/jump-if-&gt;= $write-int32-decimal:<a href='108write.subx.html#L11'>write</a>/disp8 <span id="L72" class="LineNr"> 72 </span><span class="Constant">$write-int32-decimal:push-negative</span>: <span id="L73" class="LineNr"> 73 </span> 68/push 0x2d/imm32/- <span id="L74" class="LineNr"> 74 </span><span class="Constant">$write-int32-decimal:<a href='108write.subx.html#L11'>write</a></span>: <span id="L75" class="LineNr"> 75 </span> <span class="subxComment"># edi = out</span> <span id="L76" class="LineNr"> 76 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 7/r32/edi 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+8) to edi</span> <span id="L77" class="LineNr"> 77 </span> <span class="subxComment"># var w/edx: int = out-&gt;write</span> <span id="L78" class="LineNr"> 78 </span> 8b/copy 0/mod/indirect 7/rm32/edi <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 2/r32/edx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy *edi to edx</span> <span id="L79" class="LineNr"> 79 </span> <span class="subxComment"># var curr/ecx: (addr byte) = &amp;out-&gt;data[out-&gt;write]</span> <span id="L80" class="LineNr"> 80 </span> 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx <span class="Normal"> . </span> 1/r32/ecx 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy ebx+edx+12 to ecx</span> <span id="L81" class="LineNr"> 81 </span> <span class="subxComment"># var max/ebx: (addr byte) = &amp;out-&gt;data[out-&gt;size]</span> <span id="L82" class="LineNr"> 82 </span> 8b/copy 1/mod/*+disp8 7/rm32/edi <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 3/r32/ebx 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(edi+8) to ebx</span> <span id="L83" class="LineNr"> 83 </span> 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx <span class="Normal"> . </span> 3/r32/ebx 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy edi+ebx+12 to ebx</span> <span id="L84" class="LineNr"> 84 </span><span class="Constant">$write-int32-decimal:write-loop</span>: <span id="L85" class="LineNr"> 85 </span> <span class="subxComment"># pop into eax</span> <span id="L86" class="LineNr"> 86 </span> 58/pop-to-eax <span id="L87" class="LineNr"> 87 </span> <span class="subxComment"># if (eax == sentinel) break</span> <span id="L88" class="LineNr"> 88 </span> 3d/compare-eax-and 0/imm32/sentinel <span id="L89" class="LineNr"> 89 </span> 74/jump-if-= $write-int32-decimal:write-break/disp8 <span id="L90" class="LineNr"> 90 </span> <span class="subxComment"># if (curr &gt;= max) abort</span> <span id="L91" class="LineNr"> 91 </span> 39/compare 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 3/r32/ebx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># compare ecx with ebx</span> <span id="L92" class="LineNr"> 92 </span> 73/jump-if-addr&gt;= $write-int32-decimal:<a href='501draw-text.mu.html#L519'>abort</a>/disp8 <span id="L93" class="LineNr"> 93 </span><span class="Constant">$write-int32-decimal:write-char</span>: <span id="L94" class="LineNr"> 94 </span> <span class="subxComment"># *curr = AL</span> <span id="L95" class="LineNr"> 95 </span> 88/copy-byte 0/mod/indirect 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/AL <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy AL to byte at *ecx</span> <span id="L96" class="LineNr"> 96 </span> <span class="subxComment"># ++curr</span> <span id="L97" class="LineNr"> 97 </span> 41/increment-ecx <span id="L98" class="LineNr"> 98 </span> <span class="subxComment"># ++w</span> <span id="L99" class="LineNr"> 99 </span> 42/increment-edx <span id="L100" class="LineNr">100 </span> eb/jump $write-int32-decimal:write-loop/disp8 <span id="L101" class="LineNr">101 </span><span class="Constant">$write-int32-decimal:write-break</span>: <span id="L102" class="LineNr">102 </span> <span class="subxComment"># out-&gt;write = w</span> <span id="L103" class="LineNr">103 </span> 89/copy 0/mod/indirect 7/rm32/edi <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 2/r32/edx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy edx to *edi</span> <span id="L104" class="LineNr">104 </span><span class="Constant">$write-int32-decimal:end</span>: <span id="L105" class="LineNr">105 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L106" class="LineNr">106 </span> 5f/pop-to-edi <span id="L107" class="LineNr">107 </span> 5b/pop-to-ebx <span id="L108" class="LineNr">108 </span> 5a/pop-to-edx <span id="L109" class="LineNr">109 </span> 59/pop-to-ecx <span id="L110" class="LineNr">110 </span> 58/pop-to-eax <span id="L111" class="LineNr">111 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L112" class="LineNr">112 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L113" class="LineNr">113 </span> 5d/pop-to-ebp <span id="L114" class="LineNr">114 </span> c3/return <span id="L115" class="LineNr">115 </span> <span id="L116" class="LineNr">116 </span><span class="Constant">$write-int32-decimal:<a href='501draw-text.mu.html#L519'>abort</a></span>: <span id="L117" class="LineNr">117 </span> (<a href='501draw-text.mu.html#L222'>draw-text-wrapping-right-then-down-from-cursor-over-full-screen</a> 0 <span class="Constant">&quot;write-int32-decimal: stream out of space&quot;</span> 3 0) <span class="subxComment"># 3=cyan</span> <span id="L118" class="LineNr">118 </span> { <span id="L119" class="LineNr">119 </span> eb/jump <span class="Constant">loop</span>/disp8 <span id="L120" class="LineNr">120 </span> } <span id="L121" class="LineNr">121 </span> <span class="subxComment"># never gets here</span> <span id="L122" class="LineNr">122 </span> <span id="L123" class="LineNr">123 </span><span class="subxTest">test-write-int32-decimal</span>: <span id="L124" class="LineNr">124 </span> <span class="subxH1Comment"># - check that a single-digit number converts correctly</span> <span id="L125" class="LineNr">125 </span> <span class="subxComment"># setup</span> <span id="L126" class="LineNr">126 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L127" class="LineNr">127 </span> <span class="subxS2Comment"># . . push args</span> <span id="L128" class="LineNr">128 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L129" class="LineNr">129 </span> <span class="subxS2Comment"># . . call</span> <span id="L130" class="LineNr">130 </span> e8/call <a href='106stream.subx.html#L20'>clear-stream</a>/disp32 <span id="L131" class="LineNr">131 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L132" class="LineNr">132 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L133" class="LineNr">133 </span> <span class="subxComment"># write-int32-decimal(_test-stream, 9)</span> <span id="L134" class="LineNr">134 </span> <span class="subxS2Comment"># . . push args</span> <span id="L135" class="LineNr">135 </span> 68/push 9/imm32 <span id="L136" class="LineNr">136 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L137" class="LineNr">137 </span> <span class="subxS2Comment"># . . call</span> <span id="L138" class="LineNr">138 </span> e8/call <a href='126write-int-decimal.subx.html#L8'>write-int32-decimal</a>/disp32 <span id="L139" class="LineNr">139 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L140" class="LineNr">140 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L141" class="LineNr">141 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;9&quot;, msg)</span> <span id="L142" class="LineNr">142 </span> <span class="subxS2Comment"># . . push args</span> <span id="L143" class="LineNr">143 </span> 68/push <span class="Constant">&quot;F - test-write-int32-decimal&quot;</span>/imm32 <span id="L144" class="LineNr">144 </span> 68/push <span class="Constant">&quot;9&quot;</span>/imm32 <span id="L145" class="LineNr">145 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L146" class="LineNr">146 </span> <span class="subxS2Comment"># . . call</span> <span id="L147" class="LineNr">147 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L148" class="LineNr">148 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L149" class="LineNr">149 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L150" class="LineNr">150 </span> <span class="subxS1Comment"># . end</span> <span id="L151" class="LineNr">151 </span> c3/return <span id="L152" class="LineNr">152 </span> <span id="L153" class="LineNr">153 </span><span class="subxTest">test-write-int32-decimal-zero</span>: <span id="L154" class="LineNr">154 </span> <span class="subxH1Comment"># - check that 0 converts correctly</span> <span id="L155" class="LineNr">155 </span> <span class="subxComment"># setup</span> <span id="L156" class="LineNr">156 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L157" class="LineNr">157 </span> <span class="subxS2Comment"># . . push args</span> <span id="L158" class="LineNr">158 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L159" class="LineNr">159 </span> <span class="subxS2Comment"># . . call</span> <span id="L160" class="LineNr">160 </span> e8/call <a href='106stream.subx.html#L20'>clear-stream</a>/disp32 <span id="L161" class="LineNr">161 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L162" class="LineNr">162 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L163" class="LineNr">163 </span> <span class="subxComment"># write-int32-decimal(_test-stream, 0)</span> <span id="L164" class="LineNr">164 </span> <span class="subxS2Comment"># . . push args</span> <span id="L165" class="LineNr">165 </span> 68/push 0/imm32 <span id="L166" class="LineNr">166 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L167" class="LineNr">167 </span> <span class="subxS2Comment"># . . call</span> <span id="L168" class="LineNr">168 </span> e8/call <a href='126write-int-decimal.subx.html#L8'>write-int32-decimal</a>/disp32 <span id="L169" class="LineNr">169 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L170" class="LineNr">170 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L171" class="LineNr">171 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;0&quot;, msg)</span> <span id="L172" class="LineNr">172 </span> <span class="subxS2Comment"># . . push args</span> <span id="L173" class="LineNr">173 </span> 68/push <span class="Constant">&quot;F - test-write-int32-decimal-zero&quot;</span>/imm32 <span id="L174" class="LineNr">174 </span> 68/push <span class="Constant">&quot;0&quot;</span>/imm32 <span id="L175" class="LineNr">175 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L176" class="LineNr">176 </span> <span class="subxS2Comment"># . . call</span> <span id="L177" class="LineNr">177 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L178" class="LineNr">178 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L179" class="LineNr">179 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L180" class="LineNr">180 </span> <span class="subxS1Comment"># . end</span> <span id="L181" class="LineNr">181 </span> c3/return <span id="L182" class="LineNr">182 </span> <span id="L183" class="LineNr">183 </span><span class="subxTest">test-write-int32-decimal-multiple-digits</span>: <span id="L184" class="LineNr">184 </span> <span class="subxH1Comment"># - check that a multi-digit number converts correctly</span> <span id="L185" class="LineNr">185 </span> <span class="subxComment"># setup</span> <span id="L186" class="LineNr">186 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L187" class="LineNr">187 </span> <span class="subxS2Comment"># . . push args</span> <span id="L188" class="LineNr">188 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L189" class="LineNr">189 </span> <span class="subxS2Comment"># . . call</span> <span id="L190" class="LineNr">190 </span> e8/call <a href='106stream.subx.html#L20'>clear-stream</a>/disp32 <span id="L191" class="LineNr">191 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L192" class="LineNr">192 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L193" class="LineNr">193 </span> <span class="subxComment"># write-int32-decimal(_test-stream, 10)</span> <span id="L194" class="LineNr">194 </span> <span class="subxS2Comment"># . . push args</span> <span id="L195" class="LineNr">195 </span> 68/push 0xa/imm32 <span id="L196" class="LineNr">196 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L197" class="LineNr">197 </span> <span class="subxS2Comment"># . . call</span> <span id="L198" class="LineNr">198 </span> e8/call <a href='126write-int-decimal.subx.html#L8'>write-int32-decimal</a>/disp32 <span id="L199" class="LineNr">199 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L200" class="LineNr">200 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L201" class="LineNr">201 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;10&quot;, msg)</span> <span id="L202" class="LineNr">202 </span> <span class="subxS2Comment"># . . push args</span> <span id="L203" class="LineNr">203 </span> 68/push <span class="Constant">&quot;F - test-write-int32-decimal-multiple-digits&quot;</span>/imm32 <span id="L204" class="LineNr">204 </span> 68/push <span class="Constant">&quot;10&quot;</span>/imm32 <span id="L205" class="LineNr">205 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L206" class="LineNr">206 </span> <span class="subxS2Comment"># . . call</span> <span id="L207" class="LineNr">207 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L208" class="LineNr">208 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L209" class="LineNr">209 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L210" class="LineNr">210 </span> <span class="subxS1Comment"># . end</span> <span id="L211" class="LineNr">211 </span> c3/return <span id="L212" class="LineNr">212 </span> <span id="L213" class="LineNr">213 </span><span class="subxTest">test-write-int32-decimal-negative</span>: <span id="L214" class="LineNr">214 </span> <span class="subxH1Comment"># - check that a negative single-digit number converts correctly</span> <span id="L215" class="LineNr">215 </span> <span class="subxComment"># setup</span> <span id="L216" class="LineNr">216 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L217" class="LineNr">217 </span> <span class="subxS2Comment"># . . push args</span> <span id="L218" class="LineNr">218 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L219" class="LineNr">219 </span> <span class="subxS2Comment"># . . call</span> <span id="L220" class="LineNr">220 </span> e8/call <a href='106stream.subx.html#L20'>clear-stream</a>/disp32 <span id="L221" class="LineNr">221 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L222" class="LineNr">222 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L223" class="LineNr">223 </span> <span class="subxComment"># write-int32-decimal(_test-stream, -9)</span> <span id="L224" class="LineNr">224 </span> <span class="subxS2Comment"># . . push args</span> <span id="L225" class="LineNr">225 </span> 68/push -9/imm32 <span id="L226" class="LineNr">226 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L227" class="LineNr">227 </span> <span class="subxS2Comment"># . . call</span> <span id="L228" class="LineNr">228 </span> e8/call <a href='126write-int-decimal.subx.html#L8'>write-int32-decimal</a>/disp32 <span id="L229" class="LineNr">229 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L230" class="LineNr">230 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L231" class="Folded">231 </span><span class="Folded">+-- 26 lines: #? # dump _test-stream ------------------------------------------------------------------------------------------------------------------------------------------------</span> <span id="L257" class="LineNr">257 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;-9&quot;, msg)</span> <span id="L258" class="LineNr">258 </span> <span class="subxS2Comment"># . . push args</span> <span id="L259" class="LineNr">259 </span> 68/push <span class="Constant">&quot;F - test-write-int32-decimal-negative&quot;</span>/imm32 <span id="L260" class="LineNr">260 </span> 68/push <span class="Constant">&quot;-9&quot;</span>/imm32 <span id="L261" class="LineNr">261 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L262" class="LineNr">262 </span> <span class="subxS2Comment"># . . call</span> <span id="L263" class="LineNr">263 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L264" class="LineNr">264 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L265" class="LineNr">265 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L266" class="LineNr">266 </span> <span class="subxS1Comment"># . end</span> <span id="L267" class="LineNr">267 </span> c3/return <span id="L268" class="LineNr">268 </span> <span id="L269" class="LineNr">269 </span><span class="subxTest">test-write-int32-decimal-negative-multiple-digits</span>: <span id="L270" class="LineNr">270 </span> <span class="subxH1Comment"># - check that a multi-digit number converts correctly</span> <span id="L271" class="LineNr">271 </span> <span class="subxComment"># setup</span> <span id="L272" class="LineNr">272 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L273" class="LineNr">273 </span> <span class="subxS2Comment"># . . push args</span> <span id="L274" class="LineNr">274 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L275" class="LineNr">275 </span> <span class="subxS2Comment"># . . call</span> <span id="L276" class="LineNr">276 </span> e8/call <a href='106stream.subx.html#L20'>clear-stream</a>/disp32 <span id="L277" class="LineNr">277 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L278" class="LineNr">278 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L279" class="LineNr">279 </span> <span class="subxComment"># write-int32-decimal(_test-stream, -10)</span> <span id="L280" class="LineNr">280 </span> <span class="subxS2Comment"># . . push args</span> <span id="L281" class="LineNr">281 </span> 68/push -0xa/imm32 <span id="L282" class="LineNr">282 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L283" class="LineNr">283 </span> <span class="subxS2Comment"># . . call</span> <span id="L284" class="LineNr">284 </span> e8/call <a href='126write-int-decimal.subx.html#L8'>write-int32-decimal</a>/disp32 <span id="L285" class="LineNr">285 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L286" class="LineNr">286 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L287" class="LineNr">287 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;-10&quot;, msg)</span> <span id="L288" class="LineNr">288 </span> <span class="subxS2Comment"># . . push args</span> <span id="L289" class="LineNr">289 </span> 68/push <span class="Constant">&quot;F - test-write-int32-decimal-negative-multiple-digits&quot;</span>/imm32 <span id="L290" class="LineNr">290 </span> 68/push <span class="Constant">&quot;-10&quot;</span>/imm32 <span id="L291" class="LineNr">291 </span> 68/push <a href='108write.subx.html#L125'>_test-stream</a>/imm32 <span id="L292" class="LineNr">292 </span> <span class="subxS2Comment"># . . call</span> <span id="L293" class="LineNr">293 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L294" class="LineNr">294 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L295" class="LineNr">295 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L296" class="LineNr">296 </span> <span class="subxS1Comment"># . end</span> <span id="L297" class="LineNr">297 </span> c3/return <span id="L298" class="LineNr">298 </span> <span id="L299" class="LineNr">299 </span><span class="subxFunction">is-decimal-digit?</span>: <span class="subxComment"># c: grapheme -&gt; result/eax: boolean</span> <span id="L300" class="LineNr">300 </span> <span class="subxS1Comment"># . prologue</span> <span id="L301" class="LineNr">301 </span> 55/push-ebp <span id="L302" class="LineNr">302 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L303" class="LineNr">303 </span> <span class="subxS1Comment"># . save registers</span> <span id="L304" class="LineNr">304 </span> 51/push-ecx <span id="L305" class="LineNr">305 </span> <span class="subxComment"># ecx = c</span> <span id="L306" class="LineNr">306 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 1/r32/ecx 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+8) to ecx</span> <span id="L307" class="LineNr">307 </span> <span class="subxComment"># result = false</span> <span id="L308" class="LineNr">308 </span> b8/copy-to-eax 0/imm32/false <span id="L309" class="LineNr">309 </span> <span class="subxComment"># return false if c &lt; '0'</span> <span id="L310" class="LineNr">310 </span> 81 7/subop/compare 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0x30/imm32 <span class="subxComment"># compare ecx</span> <span id="L311" class="LineNr">311 </span> 7c/jump-if-&lt; $is-decimal-digit?:end/disp8 <span id="L312" class="LineNr">312 </span> <span class="subxComment"># return (c &lt;= '9')</span> <span id="L313" class="LineNr">313 </span> 81 7/subop/compare 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0x39/imm32 <span class="subxComment"># compare ecx</span> <span id="L314" class="LineNr">314 </span> 7f/jump-if-&gt; $is-decimal-digit?:end/disp8 <span id="L315" class="LineNr">315 </span><span class="Constant">$is-decimal-digit?:true</span>: <span id="L316" class="LineNr">316 </span> b8/copy-to-eax 1/imm32/true <span id="L317" class="LineNr">317 </span><span class="Constant">$is-decimal-digit?:end</span>: <span id="L318" class="LineNr">318 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L319" class="LineNr">319 </span> 59/pop-to-ecx <span id="L320" class="LineNr">320 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L321" class="LineNr">321 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L322" class="LineNr">322 </span> 5d/pop-to-ebp <span id="L323" class="LineNr">323 </span> c3/return <span id="L324" class="LineNr">324 </span> <span id="L325" class="LineNr">325 </span><span class="subxTest">test-is-decimal-digit-below-0</span>: <span id="L326" class="LineNr">326 </span> <span class="subxComment"># eax = is-decimal-digit?(0x2f)</span> <span id="L327" class="LineNr">327 </span> <span class="subxS2Comment"># . . push args</span> <span id="L328" class="LineNr">328 </span> 68/push 0x2f/imm32 <span id="L329" class="LineNr">329 </span> <span class="subxS2Comment"># . . call</span> <span id="L330" class="LineNr">330 </span> e8/call <a href='126write-int-decimal.subx.html#L299'>is-decimal-digit?</a>/disp32 <span id="L331" class="LineNr">331 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L332" class="LineNr">332 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L333" class="LineNr">333 </span> <span class="subxComment"># check-ints-equal(eax, 0, msg)</span> <span id="L334" class="LineNr">334 </span> <span class="subxS2Comment"># . . push args</span> <span id="L335" class="LineNr">335 </span> 68/push <span class="Constant">&quot;F - test-is-decimal-digit-below-0&quot;</span>/imm32 <span id="L336" class="LineNr">336 </span> 68/push 0/imm32/false <span id="L337" class="LineNr">337 </span> 50/push-eax <span id="L338" class="LineNr">338 </span> <span class="subxS2Comment"># . . call</span> <span id="L339" class="LineNr">339 </span> e8/call <a href='502test.mu.html#L2'>check-ints-equal</a>/disp32 <span id="L340" class="LineNr">340 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L341" class="LineNr">341 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L342" class="LineNr">342 </span> c3/return <span id="L343" class="LineNr">343 </span> <span id="L344" class="LineNr">344 </span><span class="subxTest">test-is-decimal-digit-0-to-9</span>: <span id="L345" class="LineNr">345 </span> <span class="subxComment"># eax = is-decimal-digit?(0x30)</span> <span id="L346" class="LineNr">346 </span> <span class="subxS2Comment"># . . push args</span> <span id="L347" class="LineNr">347 </span> 68/push 0x30/imm32 <span id="L348" class="LineNr">348 </span> <span class="subxS2Comment"># . . call</span> <span id="L349" class="LineNr">349 </span> e8/call <a href='126write-int-decimal.subx.html#L299'>is-decimal-digit?</a>/disp32 <span id="L350" class="LineNr">350 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L351" class="LineNr">351 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L352" class="LineNr">352 </span> <span class="subxComment"># check-ints-equal(eax, 1, msg)</span> <span id="L353" class="LineNr">353 </span> <span class="subxS2Comment"># . . push args</span> <span id="L354" class="LineNr">354 </span> 68/push <span class="Constant">&quot;F - test-is-decimal-digit-at-0&quot;</span>/imm32 <span id="L355" class="LineNr">355 </span> 68/push 1/imm32/true <span id="L356" class="LineNr">356 </span> 50/push-eax <span id="L357" class="LineNr">357 </span> <span class="subxS2Comment"># . . call</span> <span id="L358" class="LineNr">358 </span> e8/call <a href='502test.mu.html#L2'>check-ints-equal</a>/disp32 <span id="L359" class="LineNr">359 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L360" class="LineNr">360 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L361" class="LineNr">361 </span> <span class="subxComment"># eax = is-decimal-digit?(0x39)</span> <span id="L362" class="LineNr">362 </span> <span class="subxS2Comment"># . . push args</span> <span id="L363" class="LineNr">363 </span> 68/push 0x39/imm32 <span id="L364" class="LineNr">364 </span> <span class="subxS2Comment"># . . call</span> <span id="L365" class="LineNr">365 </span> e8/call <a href='126write-int-decimal.subx.html#L299'>is-decimal-digit?</a>/disp32 <span id="L366" class="LineNr">366 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L367" class="LineNr">367 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L368" class="LineNr">368 </span> <span class="subxComment"># check-ints-equal(eax, 1, msg)</span> <span id="L369" class="LineNr">369 </span> <span class="subxS2Comment"># . . push args</span> <span id="L370" class="LineNr">370 </span> 68/push <span class="Constant">&quot;F - test-is-decimal-digit-at-9&quot;</span>/imm32 <span id="L371" class="LineNr">371 </span> 68/push 1/imm32/true <span id="L372" class="LineNr">372 </span> 50/push-eax <span id="L373" class="LineNr">373 </span> <span class="subxS2Comment"># . . call</span> <span id="L374" class="LineNr">374 </span> e8/call <a href='502test.mu.html#L2'>check-ints-equal</a>/disp32 <span id="L375" class="LineNr">375 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L376" class="LineNr">376 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L377" class="LineNr">377 </span> c3/return <span id="L378" class="LineNr">378 </span> <span id="L379" class="LineNr">379 </span><span class="subxTest">test-is-decimal-digit-above-9</span>: <span id="L380" class="LineNr">380 </span> <span class="subxComment"># eax = is-decimal-digit?(0x3a)</span> <span id="L381" class="LineNr">381 </span> <span class="subxS2Comment"># . . push args</span> <span id="L382" class="LineNr">382 </span> 68/push 0x3a/imm32 <span id="L383" class="LineNr">383 </span> <span class="subxS2Comment"># . . call</span> <span id="L384" class="LineNr">384 </span> e8/call <a href='126write-int-decimal.subx.html#L299'>is-decimal-digit?</a>/disp32 <span id="L385" class="LineNr">385 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L386" class="LineNr">386 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L387" class="LineNr">387 </span> <span class="subxComment"># check-ints-equal(eax, 0, msg)</span> <span id="L388" class="LineNr">388 </span> <span class="subxS2Comment"># . . push args</span> <span id="L389" class="LineNr">389 </span> 68/push <span class="Constant">&quot;F - test-is-decimal-digit-above-9&quot;</span>/imm32 <span id="L390" class="LineNr">390 </span> 68/push 0/imm32/false <span id="L391" class="LineNr">391 </span> 50/push-eax <span id="L392" class="LineNr">392 </span> <span class="subxS2Comment"># . . call</span> <span id="L393" class="LineNr">393 </span> e8/call <a href='502test.mu.html#L2'>check-ints-equal</a>/disp32 <span id="L394" class="LineNr">394 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L395" class="LineNr">395 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L396" class="LineNr">396 </span> c3/return <span id="L397" class="LineNr">397 </span> <span id="L398" class="LineNr">398 </span><span class="subxFunction">to-decimal-digit</span>: <span class="subxComment"># in: grapheme -&gt; out/eax: int</span> <span id="L399" class="LineNr">399 </span> <span class="subxS1Comment"># . prologue</span> <span id="L400" class="LineNr">400 </span> 55/push-ebp <span id="L401" class="LineNr">401 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L402" class="LineNr">402 </span> <span class="subxComment"># eax = in</span> <span id="L403" class="LineNr">403 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+8) to eax</span> <span id="L404" class="LineNr">404 </span><span class="Constant">$to-decimal-digit:check0</span>: <span id="L405" class="LineNr">405 </span> <span class="subxComment"># if (eax &lt; '0') goto abort</span> <span id="L406" class="LineNr">406 </span> 3d/compare-eax-with 0x30/imm32/0 <span id="L407" class="LineNr">407 </span> 7c/jump-if-&lt; $to-decimal-digit:<a href='501draw-text.mu.html#L519'>abort</a>/disp8 <span id="L408" class="LineNr">408 </span><span class="Constant">$to-decimal-digit:check1</span>: <span id="L409" class="LineNr">409 </span> <span class="subxComment"># if (eax &gt; '9') goto abort</span> <span id="L410" class="LineNr">410 </span> 3d/compare-eax-with 0x39/imm32/f <span id="L411" class="LineNr">411 </span> 7f/jump-if-&gt; $to-decimal-digit:<a href='501draw-text.mu.html#L519'>abort</a>/disp8 <span id="L412" class="LineNr">412 </span><span class="Constant">$to-decimal-digit:digit</span>: <span id="L413" class="LineNr">413 </span> <span class="subxComment"># return eax - '0'</span> <span id="L414" class="LineNr">414 </span> 2d/subtract-from-eax 0x30/imm32/0 <span id="L415" class="LineNr">415 </span><span class="Constant">$to-decimal-digit:end</span>: <span id="L416" class="LineNr">416 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L417" class="LineNr">417 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L418" class="LineNr">418 </span> 5d/pop-to-ebp <span id="L419" class="LineNr">419 </span> c3/return <span id="L420" class="LineNr">420 </span> <span id="L421" class="LineNr">421 </span><span class="Constant">$to-decimal-digit:<a href='501draw-text.mu.html#L519'>abort</a></span>: <span id="L422" class="LineNr">422 </span> (<a href='501draw-text.mu.html#L222'>draw-text-wrapping-right-then-down-from-cursor-over-full-screen</a> 0 <span class="Constant">&quot;to-decimal-digit: not a digit character&quot;</span> 3 0) <span class="subxComment"># 3=cyan</span> <span id="L423" class="LineNr">423 </span> { <span id="L424" class="LineNr">424 </span> eb/jump <span class="Constant">loop</span>/disp8 <span id="L425" class="LineNr">425 </span> } <span id="L426" class="LineNr">426 </span> <span class="subxComment"># never gets here</span> <span id="L427" class="LineNr">427 </span> <span id="L428" class="LineNr">428 </span><span class="subxS2Comment"># . . vim&#0058;nowrap:textwidth=0</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->