5613
Translating common bits from sigils.subx expression-aware variant of next-word to use sigils in calls.subx.
This commit is contained in:
parent
ae07bf353c
commit
904a053e9c
167
apps/calls.subx
167
apps/calls.subx
|
@ -213,4 +213,171 @@ $emit-call:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
next-word-string-or-expression-without-metadata: # line : (address stream), word-slice : (address slice)
|
||||
# pseudocode:
|
||||
# skip-chars-matching(line, ' ')
|
||||
# if line->read >= line->write # end of line
|
||||
# out = {0, 0}
|
||||
# return
|
||||
# out->start = &line->data[line->read]
|
||||
# if line->data[line->read] == '#' # comment
|
||||
# out.end = &line->data[line->write] # skip to end of line
|
||||
# return
|
||||
# if line->data[line->read] == '"' # string literal
|
||||
# skip-string(line)
|
||||
# out.end = &line->data[line->read] # no metadata
|
||||
# return
|
||||
# if line->data[line->read] == '*' # expression
|
||||
# if line->data[line->read + 1] == ' '
|
||||
# abort
|
||||
# if line->data[line->read + 1] == '('
|
||||
# skip-until-close-paren(line)
|
||||
# if (line->data[line->read] != ')'
|
||||
# abort
|
||||
# ++line->data[line->read] to skip ')'
|
||||
# out->end = &line->data[line->read]
|
||||
# return
|
||||
# if line->data[line->read] == ')'
|
||||
# ++line->read to skip ')'
|
||||
# # make sure there's nothing else of importance
|
||||
# if line->read >= line->write
|
||||
# out = {0, 0}
|
||||
# return
|
||||
# if line->data[line->read] != ' '
|
||||
# abort
|
||||
# skip-chars-matching-whitespace(line)
|
||||
# if line->read >= line->write
|
||||
# out = {0, 0}
|
||||
# return
|
||||
# if line->data[line->read] != '#' # only thing permitted after ')' is a comment
|
||||
# abort
|
||||
# out.end = &line->data[line->write] # skip to end of line
|
||||
# return
|
||||
# # default case: read a word -- but no metadata
|
||||
# while true
|
||||
# if line->read >= line->write
|
||||
# break
|
||||
# if line->data[line->read] == ' '
|
||||
# break
|
||||
# if line->data[line->read] == '/'
|
||||
# abort
|
||||
# ++line->read
|
||||
# out.end = &line->data[line->read]
|
||||
#
|
||||
# registers:
|
||||
# ecx: often line->read
|
||||
# eax: often line->data[line->read]
|
||||
#
|
||||
# . prolog
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
51/push-ecx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# skip-chars-matching(line, ' ')
|
||||
# . . push args
|
||||
68/push 0x20/imm32/space
|
||||
ff 6/subop/push *(ebp+8)
|
||||
# . . call
|
||||
e8/call skip-chars-matching/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 8/imm32
|
||||
$next-word-string-or-expression-without-metadata:check0:
|
||||
# if (line->read >= line->write) clear out and return
|
||||
# . eax = line->read
|
||||
8b/-> *(esi+4) 0/r32/eax
|
||||
# . if (eax < line->write) goto next check
|
||||
3b/compare *esi 0/r32/eax
|
||||
7c/jump-if-lesser $next-word-string-or-expression-without-metadata:check-for-comment/disp8
|
||||
# . return out = {0, 0}
|
||||
c7 0/subop/copy *edi 0/imm32
|
||||
c7 0/subop/copy *(edi+4) 0/imm32
|
||||
e9/jump $next-word-string-or-expression-without-metadata:end/disp32
|
||||
$next-word-string-or-expression-without-metadata:check-for-comment:
|
||||
# out->start = &line->data[line->read]
|
||||
8b/-> *(esi+4) 1/r32/ecx
|
||||
8d/copy-address *(esi+ecx+0xc) 0/r32/eax
|
||||
89/<- *edi 0/r32/eax
|
||||
# if (line->data[line->read] != '#') goto next check
|
||||
# . eax = line->data[line->read]
|
||||
31/xor %eax 0/r32/eax
|
||||
8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
|
||||
# . if (eax != '#') goto next check
|
||||
3d/compare-eax-and 0x23/imm32/pound
|
||||
75/jump-if-not-equal $next-word-string-or-expression-without-metadata:check-for-string-literal/disp8
|
||||
$next-word-string-or-expression-without-metadata:comment:
|
||||
# out->end = &line->data[line->write]
|
||||
8b/-> *esi 0/r32/eax
|
||||
8d/copy-address *(esi+eax+0xc) 0/r32/eax
|
||||
89/<- *(edi+4) 0/r32/eax
|
||||
# line->read = line->write # skip rest of line
|
||||
8b/-> *esi 0/r32/eax
|
||||
89/<- *(esi+4) 0/r32/eax
|
||||
# return
|
||||
eb/jump $next-word-string-or-expression-without-metadata:end/disp8
|
||||
$next-word-string-or-expression-without-metadata:check-for-string-literal:
|
||||
# if (line->data[line->read] != '"') goto next check
|
||||
3d/compare-eax-and 0x22/imm32/dquote
|
||||
75/jump-if-not-equal $next-word-string-or-expression-without-metadata:check-for-expression/disp8
|
||||
$next-word-string-or-expression-without-metadata:string-literal:
|
||||
# skip-string(line)
|
||||
# . . push args
|
||||
56/push-esi
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# out->end = &line->data[line->read]
|
||||
8b/-> *(esi+4) 1/r32/ecx
|
||||
8d/copy-address *(esi+ecx+0xc) 0/r32/eax
|
||||
89/<- *(edi+4) 0/r32/eax
|
||||
# return
|
||||
eb/jump $next-word-string-or-expression-without-metadata:end/disp8
|
||||
$next-word-string-or-expression-without-metadata:check-for-expression:
|
||||
# if (line->data[line->read] != '*') goto next check
|
||||
3d/compare-eax-and 0x2a/imm32/asterisk
|
||||
75/jump-if-not-equal $next-word-string-or-expression-without-metadata:check-for-end-of-call/disp8
|
||||
# if (line->data[line->read + 1] == ' ') goto error1
|
||||
8a/copy-byte *(esi+ecx+0xd) 0/r32/AL
|
||||
3d/compare-eax-and 0x20/imm32/space
|
||||
74/jump-if-equal $next-word-string-or-expression-without-metadata:error1/disp8
|
||||
# if (line->data[line->read] != '(') goto regular word
|
||||
3d/compare-eax-and 0x28/imm32/open-paren
|
||||
75/jump-if-not-equal $next-word-string-or-expression-without-metadata:regular-word/disp8
|
||||
$next-word-string-or-expression-without-metadata:paren:
|
||||
# skip-until-close-paren(line)
|
||||
# . . push args
|
||||
56/push-esi
|
||||
# . . call
|
||||
e8/call skip-until-close-paren/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# if (line->data[line->read] != ')') goto error2
|
||||
# . eax = line->data[line->read]
|
||||
8b/-> *(esi+4) 1/r32/ecx
|
||||
8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
|
||||
# . if (eax != ')') goto error2
|
||||
3d/compare-eax-and 0x29/imm32/close-paren
|
||||
75/jump-if-not-equal $next-word-string-or-expression-without-metadata:error2/disp8
|
||||
# skip ')'
|
||||
ff 0/subop/increment *(esi+4)
|
||||
# out->end = &line->data[line->read]
|
||||
8b/-> *(esi+4) 1/r32/ecx
|
||||
8d/copy-address *(esi+ecx+0xc) 0/r32/eax
|
||||
89/<- *(edi+4) 0/r32/eax
|
||||
# return
|
||||
eb/jump $next-word-string-or-expression-without-metadata:end/disp8
|
||||
$next-word-string-or-expression-without-metadata:end:
|
||||
# . restore registers
|
||||
5f/pop-to-edi
|
||||
5e/pop-to-esi
|
||||
59/pop-to-ecx
|
||||
58/pop-to-eax
|
||||
# . epilog
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
apps/sigils
BIN
apps/sigils
Binary file not shown.
|
@ -1650,6 +1650,32 @@ test-emit-direct-mode-2:
|
|||
# * ... -> error: no space after '*'
|
||||
# *(... -> error: *(...) expression must be all on a single line
|
||||
next-word-or-expression: # line : (address stream byte), out : (address slice)
|
||||
# pseudocode:
|
||||
# skip-chars-matching(line, ' ')
|
||||
# if line->read >= line->write # end of line
|
||||
# out = {0, 0}
|
||||
# return
|
||||
# out->start = &line->data[line->read]
|
||||
# if line->data[line->read] == '#' # comment
|
||||
# out.end = &line->data[line->write]
|
||||
# return
|
||||
# if line->data[line->read] == '"' # string literal
|
||||
# skip-string(line)
|
||||
# else if line->data[line->read] == '*' # expression
|
||||
# if line->data[line->read + 1] == ' '
|
||||
# abort
|
||||
# if line->data[line->read + 1] == '('
|
||||
# skip-until-close-paren(line)
|
||||
# if (line->data[line->read] != ')'
|
||||
# abort
|
||||
# ++line->data[line->read] to skip ')'
|
||||
# skip-chars-not-matching-whitespace(line)
|
||||
# out->end = &line->data[line->read]
|
||||
#
|
||||
# registers:
|
||||
# ecx: often line->read
|
||||
# eax: often line->data[line->read]
|
||||
#
|
||||
# . prolog
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -1690,7 +1716,7 @@ $next-word-or-expression:check-for-comment:
|
|||
# . eax = line->data[line->read]
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL
|
||||
# . compare
|
||||
# . if (eax != '#') goto next check
|
||||
3d/compare-eax-and 0x23/imm32/pound
|
||||
75/jump-if-not-equal $next-word-or-expression:check-for-string-literal/disp8
|
||||
$next-word-or-expression:comment:
|
||||
|
@ -1705,12 +1731,8 @@ $next-word-or-expression:comment:
|
|||
eb/jump $next-word-or-expression:end/disp8
|
||||
$next-word-or-expression:check-for-string-literal:
|
||||
# if (line->data[line->read] != '"') goto next check
|
||||
# . eax = line->data[line->read]
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL
|
||||
# . compare
|
||||
3d/compare-eax-and 0x22/imm32/dquote
|
||||
75/jump-if-not-equal $next-word-or-expression:check-for-paren/disp8
|
||||
75/jump-if-not-equal $next-word-or-expression:check-for-expression/disp8
|
||||
$next-word-or-expression:string-literal:
|
||||
# skip-string(line)
|
||||
# . . push args
|
||||
|
@ -1721,22 +1743,15 @@ $next-word-or-expression:string-literal:
|
|||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# skip rest of word
|
||||
eb/jump $next-word-or-expression:regular-word/disp8
|
||||
$next-word-or-expression:check-for-paren:
|
||||
$next-word-or-expression:check-for-expression:
|
||||
# if (line->data[line->read] != '*') goto next check
|
||||
# . eax = line->data[line->read]
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL
|
||||
# . compare
|
||||
3d/compare-eax-and 0x2a/imm32/asterisk
|
||||
75/jump-if-not-equal $next-word-or-expression:regular-word/disp8
|
||||
# if (line->data[line->read] == ' ') goto error1
|
||||
# if (line->data[line->read + 1] == ' ') goto error1
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xd/disp8 . # copy byte at *(esi+ecx+12+1) to AL
|
||||
# . compare
|
||||
3d/compare-eax-and 0x20/imm32/space
|
||||
74/jump-if-equal $next-word-or-expression:error1/disp8
|
||||
# if (line->data[line->read] != '(') goto regular word
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xd/disp8 . # copy byte at *(esi+ecx+12+1) to AL
|
||||
# . compare
|
||||
# if (line->data[line->read + 1] != '(') goto regular word
|
||||
3d/compare-eax-and 0x28/imm32/open-paren
|
||||
75/jump-if-not-equal $next-word-or-expression:regular-word/disp8
|
||||
$next-word-or-expression:paren:
|
||||
|
@ -1748,9 +1763,10 @@ $next-word-or-expression:paren:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# if (line->data[line->read] != ')') goto error2
|
||||
# . eax = line->data[line->read]
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL
|
||||
# . compare
|
||||
# . if (eax != ')') goto error2
|
||||
3d/compare-eax-and 0x29/imm32/close-paren
|
||||
75/jump-if-not-equal $next-word-or-expression:error2/disp8
|
||||
# skip ')'
|
||||
|
|
Loading…
Reference in New Issue