https://github.com/akkartik/mu/blob/main/linux/123slice.subx
   1 # new data structure: a slice is an open interval of addresses [start, end)
   2 # that includes 'start' but not 'end'
   3 
   4 == code
   5 #   instruction                     effective address                                                   register    displacement    immediate
   6 # . op          subop               mod             rm32          base        index         scale       r32
   7 # . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
   8 
   9 slice-empty?:  # s: (addr slice) -> result/eax: boolean
  10     # . prologue
  11     55/push-ebp
  12     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  13     # . save registers
  14     51/push-ecx
  15     # ecx = s
  16     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
  17     # if (s->start >= s->end) return true
  18     # . eax = s->start
  19     8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
  20     # . if (eax >= s->end) return true
  21     3b/compare                      1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # compare eax with *(ecx+4)
  22     b8/copy-to-eax  1/imm32/true
  23     73/jump-if-addr>=  $slice-empty?:end/disp8
  24     b8/copy-to-eax  0/imm32/false
  25 $slice-empty?:end:
  26     # . restore registers
  27     59/pop-to-ecx
  28     # . epilogue
  29     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
  30     5d/pop-to-ebp
  31     c3/return
  32 
  33 test-slice-empty-true:
  34     # . prologue
  35     55/push-ebp
  36     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  37     # var slice/ecx: slice = {34, 34}
  38     68/push  34/imm32/end
  39     68/push  34/imm32/start
  40     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
  41     # slice-empty?(slice)
  42     # . . push args
  43     51/push-ecx
  44     # . . call
  45     e8/call  slice-empty?/disp32
  46     # . . discard args
  47     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
  48     # check-ints-equal(eax, 1, msg)
  49     # . . push args
  50     68/push  "F - test-slice-empty-true"/imm32
  51     68/push  1/imm32
  52     50/push-eax
  53     # . . call
  54     e8/call  check-ints-equal/disp32
  55     # . . discard args
  56     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
  57     # . epilogue
  58     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
  59     5d/pop-to-ebp
  60     c3/return
  61 
  62 test-slice-empty-false:
  63     # . prologue
  64     55/push-ebp
  65     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  66     # var slice/ecx: slice = {32, 34}
  67     68/push  34/imm32/end
  68     68/push  32/imm32/start
  69     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
  70     # slice-empty?(slice)
  71     # . . push args
  72     51/push-ecx
  73     # . . call
  74     e8/call  slice-empty?/disp32
  75     # . . discard args
  76     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
  77     # check-ints-equal(eax, 0, msg)
  78     # . . push args
  79     68/push  "F - test-slice-empty-false"/imm32
  80     68/push  0/imm32
  81     50/push-eax
  82     # . . call
  83     e8/call  check-ints-equal/disp32
  84     # . . discard args
  85     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
  86     # . epilogue
  87     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
  88     5d/pop-to-ebp
  89     c3/return
  90 
  91 test-slice-empty-if-start-greater-than-end:
  92     # . prologue
  93     55/push-ebp
  94     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  95     # var slice/ecx: slice = {34, 32}
  96     68/push  32/imm32/end
  97     68/push  34/imm32/start
  98     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
  99     # slice-empty?(slice)
 100     # . . push args
 101     51/push-ecx
 102     # . . call
 103     e8/call  slice-empty?/disp32
 104     # . . discard args
 105     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
 106     # check-ints-equal(eax, 1, msg)
 107     # . . push args
 108     68/push  "F - test-slice-empty-if-start-greater-than-end"/imm32
 109     68/push  1/imm32
 110     50/push-eax
 111     # . . call
 112     e8/call  check-ints-equal/disp32
 113     # . . discard args
 114     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
 115     # . epilogue
 116     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
 117     5d/pop-to-ebp
 118     c3/return
 119 
 120 slice-equal?:  # s: (addr slice), p: (addr array byte) -> result/eax: boolean
 121     # pseudocode:
 122     #   if (p == 0) return (s == 0)
 123     #   currs = s->start
 124     #   maxs = s->end
 125     #   if (maxs - currs != p->size) return false
 126     #   currp = p->data
 127     #   while currs < maxs
 128     #     if (*currs != *currp) return false
 129     #     ++currs
 130     #     ++currp
 131     #   return true
 132     #
 133     # registers:
 134     #   currs: edx
 135     #   maxs: esi
 136     #   currp: ebx
 137     #   *currs: eax
 138     #   *currp: ecx
 139     #
 140     # . prologue
 141     55/push-ebp
 142     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
 143     # . save registers
 144     51/push-ecx
 145     52/push-edx
 146     53/push-ebx
 147     56/push-esi
 148     # esi = s
 149     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
 150     # var currs/edx: (addr byte) = s->start
 151     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           2/r32/edx   .               .                 # copy *esi to edx
 152     # var maxs/esi: (addr byte) = s->end
 153     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           6/r32/esi   4/disp8         .                 # copy *(esi+4) to esi
 154     # var ssize/eax: int = maxs - currs
 155     89/copy                         3/mod/direct    0/rm32/eax    .           .             .           6/r32/esi   .               .                 # copy esi to eax
 156     29/subtract                     3/mod/direct    0/rm32/eax    .           .             .           2/r32/edx   .               .                 # subtract edx from eax
 157     # ebx = p
 158     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           3/r32/ebx   0xc/disp8       .                 # copy *(ebp+12) to ebx
 159     # if (p != 0) goto next check
 160     81          7/subop/compare     3/mod/direct    3/rm32/ebx    .           .             .           .           .               0/imm32           # compare ebx
 161     75/jump-if-!=  $slice-equal?:nonnull-string/disp8
 162 $slice-equal?:null-string:
 163     # return s->start == s->end
 164     3d/compare-eax-and  0/imm32
 165     74/jump-if-=  $slice-equal?:true/disp8
 166     eb/jump  $slice-equal?:false/disp8
 167 $slice-equal?:nonnull-string:
 168     # if (ssize != p->size) return false
 169     39/compare                      0/mod/indirect  3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # compare *ebx and eax
 170     75/jump-if-!=  $slice-equal?:false/disp8
 171     # var currp/ebx: (addr byte) = p->data
 172     81          0/subop/add         3/mod/direct    3/rm32/ebx    .           .             .           .           .               4/imm32           # add to ebx
 173     # var c1/eax: byte = 0
 174     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
 175     # var c2/ecx: byte = 0
 176     31/xor                          3/mod/direct    1/rm32/ecx    .           .             .           1/r32/ecx   .               .                 # clear ecx
 177 $slice-equal?:loop:
 178     # if (currs >= maxs) return true
 179     39/compare                      3/mod/direct    2/rm32/edx    .           .             .           6/r32/esi   .               .                 # compare edx with esi
 180     73/jump-if-addr>=  $slice-equal?:true/disp8
 181     # c1 = *currp
 182     8a/copy-byte                    0/mod/indirect  3/rm32/ebx    .           .             .           0/r32/AL    .               .                 # copy byte at *ebx to AL
 183     # c2 = *currs
 184     8a/copy-byte                    0/mod/indirect  2/rm32/edx    .           .             .           1/r32/CL    .               .                 # copy byte at *edx to CL
 185     # if (c1 != c2) return false
 186     39/compare                      3/mod/direct    0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # compare eax and ecx
 187     75/jump-if-!=  $slice-equal?:false/disp8
 188     # ++currp
 189     43/increment-ebx
 190     # ++currs
 191     42/increment-edx
 192     eb/jump $slice-equal?:loop/disp8
 193 $slice-equal?:false:
 194     b8/copy-to-eax  0/imm32
 195     eb/jump  $slice-equal?:end/disp8
 196 $slice-equal?:true:
 197     b8/copy-to-eax  1/imm32
 198 $slice-equal?:end:
 199     # . restore registers
 200     5e/pop-to-esi
 201     5b/pop-to-ebx
 202     5a/pop-to-edx
 203     59/pop-to-ecx
 204     # . epilogue
 205     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
 206     5d/pop-to-ebp
 207     c3/return
 208 
 209 test-slice-equal:
 210     # - slice-equal?(slice("Abc"), "Abc") == 1
 211     # . prologue
 212     55/push-ebp
 213     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
 214     # (e
to doctor
local [text sentence stuff a b c rules keywords memory]
make "memory []
print [Hello, I am the doctor. What can I do for you?]
print [Please end your remarks with an empty line.]
print []
loop
end

;; Controlling the conversation

to loop
make "text tokenize getstuff []
make "sentence getsentence :text
analyze :sentence :keywords
print []
loop
end

;; Reading and preparing the input

to getstuff :stuff
localmake "line readlist
if emptyp :line [output :stuff]
output getstuff sentence :stuff :line
end

to tokenize :text
output map.se [tokenword ? "] :text
end

to tokenword :word :out
if emptyp :word [output :out]
if memberp first :word [, " ] [output tokenword butfirst :word :out]
if memberp first :word [. ? ! |;|] [output sentence :out ".]
output tokenword butfirst :word word :out first :word
end

to getsentence :text
make "keywords []
output getsentence1 decapitalize :text []
end

to getsentence1 :text :out
if emptyp :text [output :out]
if equalp first :text ". ~
   [ifelse emptyp :keywords ~
           [output getsentence1 decapitalize butfirst :text []] [output :out]]
checkpriority first :text
output getsentence1 butfirst :text sentence :out translate first :text
end

to decapitalize :text
if emptyp :text [output []]
output fput lowercase first :text butfirst :text
end

to checkpriority :word
localmake "priority gprop :word "priority
if emptyp :priority [stop]
if emptyp :keywords [make "keywords ( list :word ) stop]
ifelse :priority > ( gprop first :keywords "priority ) ~
       [make "keywords fput :word :keywords] ~
       [make "keywords lput :word :keywords]
end

to translate :word
localmake "new gprop :word "translation
output ifelse emptyp :new [:word] [:new]
end

;; Choosing the rule and replying

to analyze :sentence :keywords
local [rules keyword]
if emptyp :keywords [norules stop]
make "keyword first :keywords
make "rules gprop :keyword "rules
if wordp first :rules ~
   [make "keyword first :rules make "rules gprop :keyword "rules]
checkrules :keyword :rules
end

to checkrules :keyword :rules
if not match first :rules :sentence ~
   [checkrules :keyword butfirst butfirst :rules stop]
dorule first butfirst :rules
end

to dorule :rule
localmake "print first gprop :keyword :rule
pprop :keyword :rule lput :print butfirst gprop :keyword :rule
if equalp :print "newkey [analyze :sentence butfirst :keywords stop]
if wordp :print [checkrules :print gprop :print "rules stop]
if equalp first :print "pre ~
   [analyze reconstruct first butfirst :print butfirst butfirst :print stop]
print capitalize reconstruct :print
memory :keyword :sentence
end

to reconstruct :sentence
if emptyp :sentence [output []]
if not equalp ": first first :sentence ~
   [output fput first :sentence reconstruct butfirst :sentence]
output sentence reword first :sentence reconstruct butfirst :sentence
end

to reword :word
if memberp last :word [. ? ,] [output addpunct reword butlast :word last :word]
output thing butfirst :word
end

to addpunct :stuff :char
if wordp :stuff [output word :stuff :char]
if emptyp :stuff [output :char]
output sentence butlast :stuff word last :stuff :char
end

to capitalize :text
if emptyp :text [output []]
output fput (word uppercase first first :text butfirst first :text) butfirst :text
end

to memory :keyword :sentence
local [rules rule name]
make "rules gprop :keyword "memr
if emptyp :rules [stop]
if not match first :rules :sentence [stop]
make "name last :rules
make "rules gprop :keyword :name
make "rule first :rules
pprop :keyword :name lput :rule butfirst :rules
make "memory fput reconstruct :sentence :memory
end

to norules
ifelse :memflag [usememory] [lastresort]
make "memflag not :memflag
end

to lastresort
print first :lastresort
make "lastresort lput first :lastresort butfirst :lastresort
end

to usememory
if emptyp :memory [lastresort stop]
print capitalize first :memory
make "memory butfirst :memory
end

;; Predicates for patterns

to beliefp :word
output not emptyp gprop :word "belief
end

to familyp :word
output not emptyp gprop :word "family
end

;; Procedures for adding to the script

to addrule :word :pattern :results
localmake "propname gensym
pprop :word "rules (sentence gprop :word "rules list :pattern :propname)
pprop :word :propname :results
end

to addmemr :word :pattern :results
localmake "propname gensym
pprop :word "memr (sentence gprop :word "memr list :pattern :propname)
pprop :word :propname :results
end

;; data

make "gensym.number 80

make "lastresort [[I am not sure I understand you fully.] [Please go on.]
                  [What does that suggest to you?]
                  [Do you feel strongly about discussing such things?]]

make "memflag "false

pprop "alike "priority 10
pprop "alike "rules [dit]

pprop "always "priority 1
pprop "always "rules [[#] g69]
pprop "always "g69 [[Can you think of a specific example?] [When?]
                    [What incident are you thinking of?]
                    [Really, always?] [What if this never happened?]]

pprop "am "priority 0
pprop "am "translation "are
pprop "am "rules [[# are you #stuff] g18 [#] g19]
pprop "am "g18 [[Do you believe you are :stuff?] [Would you want to be :stuff?]
                [You wish I would tell you you are :stuff.]
                [What would it mean if you were :stuff?] how]
pprop "am "g19 [[Why do you say "am"?] [I don't understand that.]]

pprop "are "priority 0
pprop "are "rules [[#a there are #b you #c] g20 [# there are &stuff] g21
                   [# are I #stuff] g22 [are #] g23 [# are #stuff] g24]
pprop "are "g20 [[pre [:a there are :b] are]]
pprop "are "g21 [[What makes you think there are :stuff?]
                 [Do you usually consider :stuff?]
                 [Do you wish there were :stuff?]]
pprop "are "g22 [[Why are you interested in whether I am :stuff or not?]
                 [Would you prefer if I weren't :stuff?]
                 [Perhaps I am :stuff in your fantasies.]
                 [Do you sometimes think I am :stuff?] how]
pprop "are "g23 [how]
pprop "are "g24 [[Did you think they might not be :stuff?]
                 [Would you like it if they were not :stuff?]
                 [What if they were not :stuff?] [Possibly they are :stuff.]]

pprop "ask "priority 0
pprop "ask "rules [[# you ask #] g77 [# you ! asking #] g78 [# I #] g79 [#] g80]
pprop "ask "g77 [how]
pprop "ask "g78 [how]
pprop "ask "g79 [you]
pprop "ask "g80 [newkey]

pprop "because "priority 0
pprop "because "rules [[#] g64]
pprop "because "g64 [[Is that the real reason?]
                     [Don't any other reasons come to mind?]
                     [Does that reason seem to explain anything else?]
                     [What other reasons might there be?]
                     [You're not concealing anything from me, are you?]]

pprop "believe "belief "true

pprop "bet "belief "true

pprop "brother "family "true

pprop "can "priority 0
pprop "can "rules [[# can I #stuff] g58 [# can you #stuff] g59 [#] g60]
pprop "can "g58 [[You believe I can :stuff, don't you?] how
                 [You want me to be able to :stuff.]
                 [Perhaps you would like to be able to :stuff yourself.]]
pprop "can "g59 [[Whether or not you can :stuff depends more on you than on me.]
                 [Do you want to be able to :stuff?]
                 [Perhaps you don't want to :stuff.] how]
pprop "can "g60 [how newkey]

pprop "cant "translation "can't

pprop "certainly "priority 0
pprop "certainly "rules [yes]

pprop "children "family "true

pprop "computer "priority 50
pprop "computer "rules [[#] g17]
pprop "computer "g17 [[Do computers worry you?]
                      [Why do you mention computers?]
                      [What do you think machines have to do with your problem?]
                      [Don't you think computers can help people?]
                      [What about machines worries you?]
                      [What do you think about machines?]]

pprop "computers "priority 50
pprop "computers "rules [computer]

pprop "dad "translation "father
pprop "dad "family "true

pprop "daddy "translation "father
pprop "daddy "family "true

pprop "deutsch "priority 0
pprop "deutsch "rules [[#] g15]
pprop "deutsch "g15 [[I'm sorry, I speak only English.]]

pprop "dit "rules [[#] g72]
pprop "dit "g72 [[In what way?] [What resemblance do you see?]
                 [What does that similarity suggest to you?]
                 [What other connections do you see?]
                 [What do you suppose that resemblance means?]
                 [What is the connection, do you suppose?]
                 [Could there really be some connection?] how]

pprop "dont "translation "don't

pprop "dream "priority 3
pprop "dream "rules [[#] g9]
pprop "dream "g9 [[What does that dream suggest to you?] [Do you dream often?]
                  [What persons appear in your dreams?]
                  [Don't you believe that dream has something to do
                   with your problem?]
                  [Do you ever wish you could flee from reality?] newkey]

pprop "dreamed "priority 4
pprop "dreamed "rules [[# you dreamed #stuff] g7 [#] g8]
pprop "dreamed "g7 [[Really :stuff?]
                    [Have you ever fantasied :stuff while you were awake?]
                    [Have you dreamed :stuff before?] dream newkey]
pprop "dreamed "g8 [dream newkey]

pprop "dreams "translation "dream
pprop "dreams "priority 3
pprop "dreams "rules [dream]

pprop "dreamt "translation "dreamed
pprop "dreamt "priority 4
pprop "dreamt "rules [dreamed]

pprop "espanol "priority 0
pprop "espanol "rules [deutsch]

pprop "everybody "priority 2
pprop "everybody "rules [everyone]

pprop "everyone "priority 2
pprop "everyone "rules [[# !a:in [everyone everybody nobody noone] #] g68]
pprop "everyone "g68 [[Really, :a?] [Surely not :a.]
                      [Can you think of anyone in particular?]
                      [Who, for example?]
                      [You are thinking of a very special person.]
                      [Who, may I ask?] [Someone special perhaps.]
                      [You have a particular person in mind, don't you?]
                      [Who do you think you're talking about?]
                      [I suspect you're exaggerating a little.]]

pprop "father "family "true

pprop "feel "belief "true

pprop "francais "priority 0
pprop "francais "rules [deutsch]

pprop "hello "priority 0
pprop "hello "rules [[#] g16]
pprop "hello "g16 [[How do you do. Please state your problem.]]

pprop "how "priority 0
pprop "how "rules [[#] g63]
pprop "how "g63 [[Why do you ask?] [Does that question interest you?]
                 [What is it you really want to know?]
                 [Are such questions much on your mind?]
                 [What answer would please you most?] [What do you think?]
                 [What comes to your mind when you ask that?]
                 [Have you asked such questions before?]
                 [Have you asked anyone else?]]

pprop "husband "family "true

pprop "i "priority 0
pprop "i "translation "you
pprop "i "rules [[# you !:in [want need] #stuff] g32
                 [# you are # !stuff:in [sad unhappy depressed sick] #] g33
                 [# you are # !stuff:in [happy elated glad better] #] g34
                 [# you was #] g35 [# you !:beliefp you #stuff] g36
                 [# you # !:beliefp # i #] g37 [# you are #stuff] g38
                 [# you !:in [can't cannot] #stuff] g39
                 [# you don't #stuff] g40 [# you feel #stuff] g41
                 [# you #stuff i #] g42 [#stuff] g43]
pprop "i "g32 [[What would it mean to you if you got :stuff?]
               [Why Do you want :stuff?] [Suppose you got :stuff soon.]
               [What if you never got :stuff?]
               [What would getting :stuff mean to you?] [You really want :stuff.]
               [I suspect you really don't want :stuff.]]
pprop "i "g33 [[I'm sorry to hear you are :stuff.]
               [Do you think coming here will help you not to be :stuff?]
               [I'm sure it's not pleasant to be :stuff.]
               [Can you explain what made you :stuff?] [Please go on.]]
pprop "i "g34 [[How have I helped you to be :stuff?]
               [Has your treatment made you :stuff?]
               [What makes you :stuff just now?]
               [Can you explain why you are suddenly :stuff?]
               [Are you sure?] [What do you mean by :stuff?]]
pprop "i "g35 [was]
pprop "i "g36 [[Do you really think so?] [But you are not sure you :stuff.]
               [Do you really doubt you :stuff?]]
pprop "i "g37 [you]
pprop "i "g38 [[Is it because you are :stuff that you came to me?]
               [How long have you been :stuff?]
               [Do you believe it normal to be :stuff?] [Do you enjoy being :stuff?]]
pprop "i "g39 [[How do you know you can't :stuff?] [Have you tried?]
               [Perhaps you could :stuff now.]
               [Do you really want to be able to :stuff?]]
pprop "i "g40 [[Don't you really :stuff?] [Why don't you :stuff?]
               [Do you wish to be able to :stuff?] [Does that trouble you?]]
pprop "i "g41 [[Tell me more about such feelings.] [Do you often feel :stuff?]
               [Do you enjoy feeling :stuff?]
               [Of what does feeling :stuff remind you?]]
pprop "i "g42 [[Perhaps in your fantasy we :stuff each other.]
               [Do you wish to :stuff me?] [You seem to need to :stuff me.]
               [Do you :stuff anyone else?]]
pprop "i "g43 [[You say :stuff.] [Can you elaborate on that?]
               [Do you say :stuff for some special reason?]
               [That's quite interesting.]]

pprop "i'm "priority 0
pprop "i'm "translation "you're
pprop "i'm "rules [[# you're #stuff] g31]
pprop "i'm "g31 [[pre [you are :stuff] I]]

pprop "if "priority 3
pprop "if "rules [[#a if #b had #c] g5 [# if #stuff] g6]
pprop "if "g5 [[pre [:a if :b might have :c] if]]
pprop "if "g6 [[Do you think it's likely that :stuff?] [Do you wish that :stuff?]
               [What do you think about :stuff?]]

pprop "is "priority 0
pprop "is "rules [[&a is &b] g61 [#] g62]
pprop "is "g61 [[Suppose :a were not :b.] [Perhaps :a really is :b.]
                [Tell me more about :a.]]
pprop "is "g62 [newkey]

pprop "italiano "priority 0
pprop "italiano "rules [deutsch]

pprop "like "priority 10
pprop "like "rules [[# !:in [am is are was] # like #] g70 [#] g71]
pprop "like "g70 [dit]
pprop "like "g71 [newkey]

pprop "machine "priority 50
pprop "machine "rules [computer]

pprop "machines "priority 50
pprop "machines "rules [computer]

pprop "maybe "priority 0
pprop "maybe "rules [perhaps]

pprop "me "translation "you

pprop "mom "translation "mother
pprop "mom "family "true

pprop "mommy "translation "mother
pprop "mommy "family "true

pprop "mother "family "true

pprop "my "priority 2
pprop "my "translation "your
pprop "my "rules [[# your # !a:familyp #b] g55 [# your &stuff] g56 [#] g57]
pprop "my "g55 [[Tell me more about your family.] [Who else in your family :b?]
                [Your :a?] [What else comes to mind when you think of your :a?]]
pprop "my "g56 [[Your :stuff?] [Why do you say your :stuff?]
                [Does that suggest anything else which belongs to you?]
                [Is it important to you that your :stuff?]]
pprop "my "g57 [newkey]
pprop "my "memr [[# your &stuff] g12]
pprop "my "g12 [[Earlier you said your :stuff.] [But your :stuff.]
                [Does that have anything to do with your statement about :stuff?]]

pprop "myself "translation "yourself

pprop "name "priority 15
pprop "name "rules [[#] g14]
pprop "name "g14 [[I am not interested in names.]
                  [I've told you before I don't care about names\; please continue.]]

pprop "no "priority 0
pprop "no "rules [[no] g53 [#] g54]
pprop "no "g53 [xxyyzz [pre [x no] no]]
pprop "no "g54 [[Are you saying "no" just to be negative?]
                [You are being a bit negative.] [Why not?] [Why "no"?] newkey]

pprop "nobody "priority 2
pprop "nobody "rules [everyone]

pprop "noone "priority 2
pprop "noone "rules [everyone]

pprop "perhaps "priority 0
pprop "perhaps "rules [[#] g13]
pprop "perhaps "g13 [[You don't seem quite certain.] [Why the uncertain tone?]
                     [Can't you be more positive?] [You aren't sure.]
                     [Don't you know?]]

pprop "problem "priority 5
pprop "problem "rules [[#a !b:in [is are] your !c:in [problem problems] #] g73
                       [# your !a:in [problem problems] !b:in [is are] #c] g74
                       [#] g75]
pprop "problem "g73 [[:a :b your :c.] [Are you sure :a :b your :c?]
                     [Perhaps :a :b not your real :c.]
                     [You think you have problems?]
                     [Do you often think about :a?]]
pprop "problem "g74 [[Your :a :b :c?] [Are you sure your :a :b :c?]
                     [Perhaps your real :a :b not :c.] [You think you have problems?]]
pprop "problem "g75 [[Please continue, this may be interesting.]
                     [Have you any other problems you wish to discuss?]
                     [Perhaps you'd rather change the subject.]
                     [You seem a bit uneasy.] newkey]
pprop "problem "memr [[#stuff is your problem #] g76]
pprop "problem "g76 [[Earlier you mentioned :stuff.]
                     [Let's talk further about :stuff.]
                     [Tell me more about :stuff.]
                     [You haven't mentioned :stuff for a while.]]

pprop "problems "priority 5
pprop "problems "rules [problem]

pprop "remember "priority 5
pprop "remember "rules [[# you remember #stuff] g2 [# do I remember #stuff] g3 [#] g4]
pprop "remember "g2 [[Do you often think of :stuff?]
                     [Does thinking of :stuff bring anything else to mind?]
                     [What else do you remember?]
                     [Why do you remember :stuff just now?]
                     [What in the present situation reminds you of :stuff?]]
pprop "remember "g3 [[Did you think I would forget :stuff?]
                     [Why do you think I should recall :stuff now?]
                     [What about :stuff?] what [You mentioned :stuff.]]
pprop "remember "g4 [newkey]

pprop "same "priority 10
pprop "same "rules [dit]

pprop "sister "family "true

pprop "sorry "priority 0
pprop "sorry "rules [[#] g1]
pprop "sorry "g1 [[Please don't apologize.] [Apologies are not necessary.]
                  [What feelings do you have when you apologize?]
                  [I've told you that apologies are not required.]]

pprop "svenska "priority 0
pprop "svenska "rules [deutsch]

pprop "think "belief "true

pprop "was "priority 2
pprop "was "rules [[# was you #stuff] g26 [# you was #stuff] g27
                   [# was I #stuff] g28 [#] g29]
pprop "was "g26 [[What if you were :stuff?] [Do you think you were :stuff?]
                 [Were you :stuff?] [What would it mean if you were :stuff?]
                 [What does " :stuff " suggest to you?] how]
pprop "was "g27 [[Were you really?] [Why do you tell me you were :stuff now?]
                 [Perhaps I already knew you were :stuff.]]
pprop "was "g28 [[Would you like to believe I was :stuff?]
                 [What suggests that I was :stuff?] [What do you think?]
                 [Perhaps I was :stuff.] [What if I had been :stuff?]]
pprop "was "g29 [newkey]

pprop "we "translation "you
pprop "we "priority 0
pprop "we "rules [I]

pprop "were "priority 0
pprop "were "translation "was
pprop "were "rules [was]

pprop "what "priority 0
pprop "what "rules [[!:in [what where] #] g10 [# !a:in [what where] #b] g11]
pprop "what "g10 [how]
pprop "what "g11 [[Tell me about :a :b.] [:a :b?] [Do you want me to tell you :a :b?]
                  [Really.] [I see.] newkey]

pprop "where "priority 0
pprop "where "rules [how]

pprop "why "priority 0
pprop "why "rules [[# why don't I #stuff] g65 [# why can't you #stuff] g66 [#] g67]
pprop "why "g65 [[Do you believe I don't :stuff?]
                 [Perhaps I will :stuff in good time.]
                 [Should you :stuff yourself?] [You want me to :stuff?] how]
pprop "why "g66 [[Do you think you should be able to :stuff?]
                 [Do you want to be able to :stuff?]
                 [Do you believe this will help you to :stuff?]
                 [Have you any idea why you can't :stuff?] how]
pprop "why "g67 [[Why indeed?] [Why "why"?] [Why not?] how newkey]

pprop "wife "family "true

pprop "wish "belief "true

pprop "wont "translation "won't

pprop "xxyyzz "priority 0
pprop "xxyyzz "rules [[#] g50]
pprop "xxyyzz "g50 [[You're being somewhat short with me.]
                    [You don't seem very talkative today.]
                    [Perhaps you'd rather talk about something else.]
                    [Are you using monosyllables for some reason?] newkey]

pprop "yes "priority 0
pprop "yes "rules [[yes] g51 [#] g52]
pprop "yes "g51 [xxyyzz [pre [x yes] yes]]
pprop "yes "g52 [[You seem quite positive.] [You are sure.] [I see.]
                 [I understand.] newkey]

pprop "you "priority 0
pprop "you "translation "I
pprop "you "rules [[# I remind you of #] g44 [# I are # you #] g45
                   [# I # are #stuff] g46 [# I #stuff you] g47
                   [# I &stuff] g48 [#] g49]
pprop "you "g44 [dit]
pprop "you "g45 [newkey]
pprop "you "g46 [[What makes you think I am :stuff?]
                 [Does it please you to believe I am :stuff?]
                 [Perhaps you would like to be :stuff.]
                 [Do you sometimes wish you were :stuff?]]
pprop "you "g47 [[Why do you think I :stuff you?]
                 [You like to think I :stuff you, don't you?]
                 [What makes you think I :stuff you?] [Really, I :stuff you?]
                 [Do you wish to believe I :stuff you?]
                 [Suppose I did :stuff you. what would that mean?]
                 [Does someone else believe I :stuff you?]]
pprop "you "g48 [[We were discussing you, not me.] [Oh, I :stuff?]
                 [Is this really relevant to your problem?] [Perhaps I do :stuff.]
                 [Are you glad to know I :stuff?] [Do you :stuff?]
                 [What are your feelings now?]]
pprop "you "g49 [newkey]

pprop "you're "priority 0
pprop "you're "translation "I'm
pprop "you're "rules [[# I'm #stuff] g30]
pprop "you're "g30 [[pre [I are :stuff] you]]

pprop "your "priority 0
pprop "your "translation "my
pprop "your "rules [[# my #stuff] g25]
pprop "your "g25 [[Why are you concerned over my :stuff?]
                  [What about your own :stuff?]
                  [Are you worried about someone else's :stuff?]
                  [Really, my :stuff?]]

pprop "yourself "translation "myself


to match :pat :sen
local [special.var special.pred special.buffer in.list]
if or wordp :pat wordp :sen [output "false]
if emptyp :pat [output emptyp :sen]
if listp first :pat [output special fput "!: :pat :sen]
if memberp first first :pat [? # ! & @ ^] [output special :pat :sen]
if emptyp :sen [output "false]
if equalp first :pat first :sen [output match butfirst :pat butfirst :sen]
output "false
end

;; Parsing quantifiers

to special :pat :sen
set.special parse.special butfirst first :pat "
output run word "match first first :pat
end

to parse.special :word :var
if emptyp :word [output list :var "always]
if equalp first :word ": [output list :var butfirst :word]
output parse.special butfirst :word word :var first :word
end

to set.special :list
make "special.var first :list
make "special.pred last :list
if emptyp :special.var [make "special.var "special.buffer]
if memberp :special.pred [in anyof] [set.in]
if not emptyp :special.pred [stop]
make "special.pred first butfirst :pat
make "pat fput first :pat butfirst butfirst :pat
end

to set.in
make "in.list first butfirst :pat
make "pat fput first :pat butfirst butfirst :pat
end

;; Exactly one match

to match!
if emptyp :sen [output "false]
if not try.pred [output "false]
make :special.var first :sen
output match butfirst :pat butfirst :sen
end

;; Zero or one match

to match?
make :special.var []
if emptyp :sen [output match butfirst :pat :sen]
if not try.pred [output match butfirst :pat :sen]
make :special.var first :sen
if match butfirst :pat butfirst :sen [output "true]
make :special.var []
output match butfirst :pat :sen
end

;; Zero or more matches

to match#
make :special.var []
output #test #gather :sen
end

to #gather :sen
if emptyp :sen [output :sen]
if not try.pred [output :sen]
make :special.var lput first :sen thing :special.var
output #gather butfirst :sen
end

to #test :sen
if match butfirst :pat :sen [output "true]
if emptyp thing :special.var [output "false]
output #test2 fput last thing :special.var :sen
end

to #test2 :sen
make :special.var butlast thing :special.var
output #test :sen
end

;; One or more matches

to match&
output &test match#
end

to &test :tf
if emptyp thing :special.var [output "false]
output :tf
end

;; Zero or more matches (as few as possible)

to match^
make :special.var []
output ^test :sen
end

to ^test :sen
if match butfirst :pat :sen [output "true]
if emptyp :sen [output "false]
if not try.pred [output "false]
make :special.var lput first :sen thing :special.var
output ^test butfirst :sen
end

;; Match words in a group

to match@
make :special.var :sen
output @test []
end

to @test :sen
if @try.pred [if match butfirst :pat :sen [output "true]]
if emptyp thing :special.var [output "false]
output @test2 fput last thing :special.var :sen
end

to @test2 :sen
make :special.var butlast thing :special.var
output @test :sen
end

;; Applying the predicates

to try.pred
if listp :special.pred [output match :special.pred first :sen]
output run list :special.pred quoted first :sen
end

to quoted :thing
if listp :thing [output :thing]
output word "" :thing
end

to @try.pred
if listp :special.pred [output match :special.pred thing :special.var]
output run list :special.pred thing :special.var
end

;; Special predicates

to always :x
output "true
end

to in :word
output memberp :word :in.list
end

to anyof :sen
output anyof1 :sen :in.list
end

to anyof1 :sen :pats
if emptyp :pats [output "false]
if match first :pats :sen [output "true]
output anyof1 :sen butfirst :pats
end
0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 459 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 460 05/add-to-eax 4/imm32 461 # var slice/ecx: slice = {eax, ecx} 462 51/push-ecx 463 50/push-eax 464 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 465 # eax = slice-equal?(ecx, 0) 466 # . . push args 467 68/push 0/imm32 468 51/push-ecx 469 # . . call 470 e8/call slice-equal?/disp32 471 # . . discard args 472 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 473 # check-ints-equal(eax, 0, msg) 474 # . . push args 475 68/push "F - test-slice-equal-with-null"/imm32 476 68/push 0/imm32 477 50/push-eax 478 # . . call 479 e8/call check-ints-equal/disp32 480 # . . discard args 481 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 482 # . epilogue 483 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 484 5d/pop-to-ebp 485 c3/return 486 487 slice-starts-with?: # s: (addr slice), head: (addr array byte) -> result/eax: boolean 488 # pseudocode 489 # hsize = head->size 490 # if (hsize > s->end - s->start) return false 491 # i = 0 492 # currs = s->start 493 # currp = head->data 494 # while i < hsize 495 # if (*currs != *currh) return false 496 # ++i 497 # ++currs 498 # ++currh 499 # return true 500 # 501 # registers: 502 # currs: esi 503 # currh: edi 504 # *currs: eax 505 # *currh: ebx 506 # i: ecx 507 # hsize: edx 508 # 509 # . prologue 510 55/push-ebp 511 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 512 # . save registers 513 51/push-ecx 514 52/push-edx 515 53/push-ebx 516 56/push-esi 517 57/push-edi 518 # esi = s 519 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi 520 # var lens/ecx: int = s->end - s->start 521 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx 522 2b/subtract 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # subtract *esi from ecx 523 # edi = head 524 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 525 # var hsize/edx: int = head->size 526 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx 527 # if (hsize > lens) return false 528 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx 529 7f/jump-if-> $slice-starts-with?:false/disp8 530 # var currs/esi: (addr byte) = s->start 531 8b/subtract 0/mod/indirect 6/rm32/esi . . . 6/r32/esi . . # copy *esi to esi 532 # var currh/edi: (addr byte) = head->data 533 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi 534 # var i/ecx: int = 0 535 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx 536 # var c1/eax: byte = 0 537 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 538 # var c2/ebx: byte = 0 539 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx 540 $slice-starts-with?:loop: 541 # if (i >= hsize) return true 542 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 543 7d/jump-if->= $slice-starts-with?:true/disp8 544 # c1 = *currs 545 8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL 546 # c2 = *currh 547 8a/copy-byte 0/mod/indirect 7/rm32/edi . . . 3/r32/BL . . # copy byte at *edi to BL 548 # if (c1 != c2) return false 549 39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx 550 75/jump-if-!= $slice-starts-with?:false/disp8 551 # ++i 552 41/increment-ecx 553 # ++currs 554 46/increment-esi 555 # ++currh 556 47/increment-edi 557 eb/jump $slice-starts-with?:loop/disp8 558 $slice-starts-with?:true: 559 b8/copy-to-eax 1/imm32 560 eb/jump $slice-starts-with?:end/disp8 561 $slice-starts-with?:false: 562 b8/copy-to-eax 0/imm32 563 $slice-starts-with?:end: 564 # . restore registers 565 5f/pop-to-edi 566 5e/pop-to-esi 567 5b/pop-to-ebx 568 5a/pop-to-edx 569 59/pop-to-ecx 570 # . epilogue 571 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 572 5d/pop-to-ebp 573 c3/return 574 575 test-slice-starts-with-single-character: 576 # - slice-starts-with?(slice("Abc"), "A") == 1 577 # . prologue 578 55/push-ebp 579 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 580 # (eax..ecx) = "Abc" 581 b8/copy-to-eax "Abc"/imm32 582 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 583 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 584 05/add-to-eax 4/imm32 585 # var slice/ecx: slice = {eax, ecx} 586 51/push-ecx 587 50/push-eax 588 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 589 # eax = slice-starts-with?(ecx, "A") 590 # . . push args 591 68/push "A"/imm32 592 51/push-ecx 593 # . . call 594 e8/call slice-starts-with?/disp32 595 # . . discard args 596 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 597 # check-ints-equal(eax, 1, msg) 598 # . . push args 599 68/push "F - test-slice-starts-with-single-character"/imm32 600 68/push 1/imm32 601 50/push-eax 602 # . . call 603 e8/call check-ints-equal/disp32 604 # . . discard args 605 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 606 # . epilogue 607 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 608 5d/pop-to-ebp 609 c3/return 610 611 test-slice-starts-with-empty-string: 612 # - slice-starts-with?(slice("Abc"), "") == 1 613 # . prologue 614 55/push-ebp 615 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 616 # (eax..ecx) = "Abc" 617 b8/copy-to-eax "Abc"/imm32 618 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 619 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 620 05/add-to-eax 4/imm32 621 # var slice/ecx: slice = {eax, ecx} 622 51/push-ecx 623 50/push-eax 624 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 625 # eax = slice-starts-with?(ecx, "") 626 # . . push args 627 68/push ""/imm32 628 51/push-ecx 629 # . . call 630 e8/call slice-starts-with?/disp32 631 # . . discard args 632 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 633 # check-ints-equal(eax, 1, msg) 634 # . . push args 635 68/push "F - test-slice-starts-with-empty-string"/imm32 636 68/push 1/imm32 637 50/push-eax 638 # . . call 639 e8/call check-ints-equal/disp32 640 # . . discard args 641 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 642 # . epilogue 643 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 644 5d/pop-to-ebp 645 c3/return 646 647 test-slice-starts-with-multiple-characters: 648 # - slice-starts-with?(slice("Abc"), "Ab") == 1 649 # . prologue 650 55/push-ebp 651 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 652 # (eax..ecx) = "Abc" 653 b8/copy-to-eax "Abc"/imm32 654 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 655 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 656 05/add-to-eax 4/imm32 657 # var slice/ecx: slice = {eax, ecx} 658 51/push-ecx 659 50/push-eax 660 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 661 # eax = slice-starts-with?(ecx, "Ab") 662 # . . push args 663 68/push "Ab"/imm32 664 51/push-ecx 665 # . . call 666 e8/call slice-starts-with?/disp32 667 # . . discard args 668 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 669 # check-ints-equal(eax, 1, msg) 670 # . . push args 671 68/push "F - test-slice-starts-with-multiple-characters"/imm32 672 68/push 1/imm32 673 50/push-eax 674 # . . call 675 e8/call check-ints-equal/disp32 676 # . . discard args 677 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 678 # . epilogue 679 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 680 5d/pop-to-ebp 681 c3/return 682 683 test-slice-starts-with-entire-string: 684 # - slice-starts-with?(slice("Abc"), "Abc") == 1 685 # . prologue 686 55/push-ebp 687 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 688 # (eax..ecx) = "Abc" 689 b8/copy-to-eax "Abc"/imm32 690 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 691 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 692 05/add-to-eax 4/imm32 693 # var slice/ecx: slice = {eax, ecx} 694 51/push-ecx 695 50/push-eax 696 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 697 # eax = slice-starts-with?(ecx, "Abc") 698 # . . push args 699 68/push "Abc"/imm32 700 51/push-ecx 701 # . . call 702 e8/call slice-starts-with?/disp32 703 # . . discard args 704 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 705 # check-ints-equal(eax, 1, msg) 706 # . . push args 707 68/push "F - test-slice-starts-with-entire-string"/imm32 708 68/push 1/imm32 709 50/push-eax 710 # . . call 711 e8/call check-ints-equal/disp32 712 # . . discard args 713 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 714 # . epilogue 715 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 716 5d/pop-to-ebp 717 c3/return 718 719 test-slice-starts-with-fails: 720 # - slice-starts-with?(slice("Abc"), "Abd") == 1 721 # . prologue 722 55/push-ebp 723 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 724 # (eax..ecx) = "Abc" 725 b8/copy-to-eax "Abc"/imm32 726 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 727 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 728 05/add-to-eax 4/imm32 729 # var slice/ecx: slice = {eax, ecx} 730 51/push-ecx 731 50/push-eax 732 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 733 # eax = slice-starts-with?(ecx, "Abd") 734 # . . push args 735 68/push "Abd"/imm32 736 51/push-ecx 737 # . . call 738 e8/call slice-starts-with?/disp32 739 # . . discard args 740 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 741 # check-ints-equal(eax, 0, msg) 742 # . . push args 743 68/push "F - test-slice-starts-with-fails"/imm32 744 68/push 0/imm32 745 50/push-eax 746 # . . call 747 e8/call check-ints-equal/disp32 748 # . . discard args 749 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 750 # . epilogue 751 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 752 5d/pop-to-ebp 753 c3/return 754 755 test-slice-starts-with-fails-2: 756 # - slice-starts-with?(slice("Abc"), "Ac") == 1 757 # . prologue 758 55/push-ebp 759 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 760 # (eax..ecx) = "Abc" 761 b8/copy-to-eax "Abc"/imm32 762 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 763 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 764 05/add-to-eax 4/imm32 765 # var slice/ecx: slice = {eax, ecx} 766 51/push-ecx 767 50/push-eax 768 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 769 # eax = slice-starts-with?(ecx, "Ac") 770 # . . push args 771 68/push "Ac"/imm32 772 51/push-ecx 773 # . . call 774 e8/call slice-starts-with?/disp32 775 # . . discard args 776 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 777 # check-ints-equal(eax, 0, msg) 778 # . . push args 779 68/push "F - test-slice-starts-with-fails-2"/imm32 780 68/push 0/imm32 781 50/push-eax 782 # . . call 783 e8/call check-ints-equal/disp32 784 # . . discard args 785 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 786 # . epilogue 787 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 788 5d/pop-to-ebp 789 c3/return 790 791 # write a slice to a stream 792 # abort if the stream doesn't have enough space 793 write-slice: # out: (addr stream byte), s: (addr slice) 794 # . prologue 795 55/push-ebp 796 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 797 # . save registers 798 50/push-eax 799 51/push-ecx 800 52/push-edx 801 53/push-ebx 802 56/push-esi 803 57/push-edi 804 # esi = s 805 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 806 # var curr/ecx: (addr byte) = s->start 807 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 808 # var max/esi: (addr byte) = s->end 809 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi 810 # edi = out 811 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 812 # edx = out->size 813 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx 814 # ebx = out->write 815 8b/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy *edi to ebx 816 $write-slice:loop: 817 # if (curr >= max) break 818 39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi 819 73/jump-if-addr>= $write-slice:loop-end/disp8 820 # if (out->write >= out->size) abort 821 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx 822 7d/jump-if->= $write-slice:abort/disp8 823 # out->data[out->write] = *in 824 # . AL = *in 825 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 826 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 827 # . out->data[out->write] = AL 828 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 0/r32/AL 0xc/disp8 . # copy AL to *(edi+ebx+12) 829 # ++out->write 830 43/increment-ebx 831 # ++in 832 41/increment-ecx 833 eb/jump $write-slice:loop/disp8 834 $write-slice:loop-end: 835 # persist out->write 836 89/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy ebx to *edi 837 $write-slice:end: 838 # . restore registers 839 5f/pop-to-edi 840 5e/pop-to-esi 841 5b/pop-to-ebx 842 5a/pop-to-edx 843 59/pop-to-ecx 844 58/pop-to-eax 845 # . epilogue 846 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 847 5d/pop-to-ebp 848 c3/return 849 850 $write-slice:abort: 851 # . _write(2/stderr, error) 852 # . . push args 853 68/push "write-slice: out of space"/imm32 854 68/push 2/imm32/stderr 855 # . . call 856 e8/call _write/disp32 857 # . . discard args 858 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 859 # . syscall(exit, 1) 860 bb/copy-to-ebx 1/imm32 861 e8/call syscall_exit/disp32 862 # never gets here 863 864 test-write-slice: 865 # . prologue 866 55/push-ebp 867 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 868 # setup 869 # . clear-stream(_test-stream) 870 # . . push args 871 68/push _test-stream/imm32 872 # . . call 873 e8/call clear-stream/disp32 874 # . . discard args 875 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 876 # (eax..ecx) = "Abc" 877 b8/copy-to-eax "Abc"/imm32 878 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 879 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 880 05/add-to-eax 4/imm32 881 # var slice/ecx: slice = {eax, ecx} 882 51/push-ecx 883 50/push-eax 884 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 885 # write-slice(_test-stream, slice) 886 # . . push args 887 51/push-ecx 888 68/push _test-stream/imm32 889 # . . call 890 e8/call write-slice/disp32 891 # . . discard args 892 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 893 # check-stream-equal(_test-stream, "Abc", msg) 894 # . . push args 895 68/push "F - test-write-slice"/imm32 896 68/push "Abc"/imm32 897 68/push _test-stream/imm32 898 # . . call 899 e8/call check-stream-equal/disp32 900 # . . discard args 901 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 902 # . epilogue 903 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 904 5d/pop-to-ebp 905 c3/return 906 907 # write a slice to a buffered-file 908 write-slice-buffered: # out: (addr buffered-file), s: (addr slice) 909 # . prologue 910 55/push-ebp 911 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 912 # . save registers 913 50/push-eax 914 51/push-ecx 915 52/push-edx 916 53/push-ebx 917 56/push-esi 918 57/push-edi 919 # esi = s 920 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 921 # var curr/ecx: (addr byte) = s->start 922 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 923 # var max/esi: (addr byte) = s->end 924 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi 925 # edi = out 926 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 927 # edx = out->size 928 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 0xc/disp8 . # copy *(edi+12) to edx 929 # ebx = out->write 930 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy *(edi+4) to ebx 931 $write-slice-buffered:loop: 932 # if (curr >= max) break 933 39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi 934 73/jump-if-addr>= $write-slice-buffered:loop-end/disp8 935 # if (out->write >= out->size) flush and clear out's stream 936 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx 937 7c/jump-if-< $write-slice-buffered:to-stream/disp8 938 # . persist out->write 939 89/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy ebx to *(edi+4) 940 # . flush(out) 941 # . . push args 942 57/push-edi 943 # . . call 944 e8/call flush/disp32 945 # . . discard args 946 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 947 # . clear-stream(stream = out+4) 948 # . . push args 949 8d/copy-address 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 4/disp8 . # copy edi+4 to eax 950 50/push-eax 951 # . . call 952 e8/call clear-stream/disp32 953 # . . discard args 954 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 955 # . out->write must now be 0; update its cache at ebx 956 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx 957 $write-slice-buffered:to-stream: 958 # out->data[out->write] = *in 959 # . AL = *in 960 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 961 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 962 # . out->data[out->write] = AL 963 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 0/r32/AL 0x10/disp8 . # copy AL to *(edi+ebx+16) 964 # ++out->write 965 43/increment-ebx 966 # ++in 967 41/increment-ecx 968 eb/jump $write-slice-buffered:loop/disp8 969 $write-slice-buffered:loop-end: 970 # persist necessary variables from registers 971 89/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy ebx to *(edi+4) 972 $write-slice-buffered:end: 973 # . restore registers 974 5f/pop-to-edi 975 5e/pop-to-esi 976 5b/pop-to-ebx 977 5a/pop-to-edx 978 59/pop-to-ecx 979 58/pop-to-eax 980 # . epilogue 981 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 982 5d/pop-to-ebp 983 c3/return 984 985 test-write-slice-buffered: 986 # . prologue 987 55/push-ebp 988 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 989 # setup 990 # . clear-stream(_test-stream) 991 # . . push args 992 68/push _test-stream/imm32 993 # . . call 994 e8/call clear-stream/disp32 995 # . . discard args 996 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 997 # . clear-stream($_test-buffered-file->buffer) 998 # . . push args 999 68/push $_test-buffered-file->buffer/imm32 1000 # . . call 1001 e8/call clear-stream/disp32 1002 # . . discard args 1003 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 1004 # (eax..ecx) = "Abc" 1005 b8/copy-to-eax "Abc"/imm32 1006 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 1007 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 1008 05/add-to-eax 4/imm32 1009 # var slice/ecx: slice = {eax, ecx} 1010 51/push-ecx 1011 50/push-eax 1012 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 1013 # write-slice-buffered(_test-buffered-file, slice) 1014 # . . push args 1015 51/push-ecx 1016 68/push _test-buffered-file/imm32 1017 # . . call 1018 e8/call write-slice-buffered/disp32 1019 # . . discard args 1020 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1021 # flush(_test-buffered-file) 1022 # . . push args 1023 68/push _test-buffered-file/imm32 1024 # . . call 1025 e8/call flush/disp32 1026 # . . discard args 1027 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 1028 # check-stream-equal(_test-stream, "Abc", msg) 1029 # . . push args 1030 68/push "F - test-write-slice-buffered"/imm32 1031 68/push "Abc"/imm32 1032 68/push _test-stream/imm32 1033 # . . call 1034 e8/call check-stream-equal/disp32 1035 # . . discard args 1036 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1037 # . epilogue 1038 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 1039 5d/pop-to-ebp 1040 c3/return 1041 1042 # copy a slice into a new (dynamically allocated) string 1043 slice-to-string: # ad: (addr allocation-descriptor), in: (addr slice), out: (addr handle array byte) 1044 # . prologue 1045 55/push-ebp 1046 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 1047 # . save registers 1048 50/push-eax 1049 51/push-ecx 1050 52/push-edx 1051 53/push-ebx 1052 56/push-esi 1053 # esi = in 1054 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 1055 # var curr/edx: (addr byte) = in->start 1056 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 1057 # var max/ebx: (addr byte) = in->end 1058 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 3/r32/ebx 4/disp8 . # copy *(esi+4) to ebx 1059 # var size/ecx: int = max - curr + 4 # total size of output string (including the initial 'size' field) 1060 89/copy 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # copy ebx to ecx 1061 29/subtract 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # subtract edx from ecx 1062 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx 1063 # allocate(ad, size, out) 1064 # . . push args 1065 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) 1066 51/push-ecx 1067 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) 1068 # . . call 1069 e8/call allocate/disp32 1070 # . . discard args 1071 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1072 # eax = out->payload 1073 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax 1074 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax 1075 # skip payload->allocid 1076 05/add-to-eax 4/imm32 1077 # if (eax == 0) abort 1078 3d/compare-eax-and 0/imm32 1079 74/jump-if-= $slice-to-string:abort/disp8 1080 # out->size = size-4 1081 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax 1082 81 5/subop/subtract 0/mod/indirect 0/rm32/eax . . . . . 4/imm32 # subtract 4 from *eax 1083 # save out 1084 50/push-eax 1085 $slice-to-string:initialize: 1086 # eax = _append-4(eax+4, eax+size, curr, max) # clobbering ecx 1087 # . . push args 1088 53/push-ebx 1089 52/push-edx 1090 # . . push eax+size (clobbering ecx) 1091 01/add 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # add eax to ecx 1092 51/push-ecx 1093 # . . push eax+4 (clobbering eax) 1094 81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 4/imm32 # add to eax 1095 50/push-eax 1096 # . . call 1097 e8/call _append-4/disp32 1098 # . . discard args 1099 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp 1100 # restore out (assumes _append-4 can't error) 1101 58/pop-to-eax 1102 $slice-to-string:end: 1103 # . restore registers 1104 5e/pop-to-esi 1105 5b/pop-to-ebx 1106 5a/pop-to-edx 1107 59/pop-to-ecx 1108 58/pop-to-eax 1109 # . epilogue 1110 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 1111 5d/pop-to-ebp 1112 c3/return 1113 1114 $slice-to-string:abort: 1115 # . _write(2/stderr, error) 1116 # . . push args 1117 68/push "slice-to-string: out of space\n"/imm32 1118 68/push 2/imm32/stderr 1119 # . . call 1120 e8/call _write/disp32 1121 # . . discard args 1122 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1123 # . syscall(exit, 1) 1124 bb/copy-to-ebx 1/imm32 1125 e8/call syscall_exit/disp32 1126 # never gets here 1127 1128 test-slice-to-string: 1129 # . prologue 1130 55/push-ebp 1131 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 1132 # var heap/edx: allocation-descriptor 1133 68/push 0/imm32/limit 1134 68/push 0/imm32/curr 1135 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 1136 # heap = new-segment(512) 1137 # . . push args 1138 52/push-edx 1139 68/push 0x200/imm32 1140 # . . call 1141 e8/call new-segment/disp32 1142 # . . discard args 1143 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1144 # (eax..ecx) = "Abc" 1145 b8/copy-to-eax "Abc"/imm32 1146 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 1147 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 1148 05/add-to-eax 4/imm32 1149 # var slice/ecx: slice = {eax, ecx} 1150 51/push-ecx 1151 50/push-eax 1152 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 1153 # var h/ebx: (handle array byte) 1154 68/push 0/imm32 1155 68/push 0/imm32 1156 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx 1157 # slice-to-string(heap, slice, h) 1158 # . . push args 1159 53/push-ebx 1160 51/push-ecx 1161 52/push-edx 1162 # . . call 1163 e8/call slice-to-string/disp32 1164 # . . discard args 1165 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1166 # eax = h->payload 1167 8b/copy 1/mod/*+disp8 3/rm32/ebx . . . 0/r32/eax 4/disp8 . # copy *(ebx+4) to eax 1168 # skip payload->allocid 1169 05/add-to-eax 4/imm32 1170 +-- 26 lines: #? # dump eax --------------------------------------------------------------------------------------------------------------------------------------------------------- 1196 # eax = string-equal?(eax, "Abc") 1197 # . . push args 1198 68/push "Abc"/imm32 1199 50/push-eax 1200 # . . call 1201 e8/call string-equal?/disp32 1202 # . . discard args 1203 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1204 # check-ints-equal(eax, 1, msg) 1205 # . . push args 1206 68/push "F - test-slice-to-string"/imm32 1207 68/push 1/imm32/true 1208 50/push-eax 1209 # . . call 1210 e8/call check-ints-equal/disp32 1211 # . . discard args 1212 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1213 # . reclaim locals 1214 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x18/imm32 # add to esp 1215 # . epilogue 1216 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 1217 5d/pop-to-ebp 1218 c3/return 1219 1220 # . . vim:nowrap:textwidth=0