}
;;; ========================================
-;;; Macro WORD starts a FORTH word definition in this code
-;;;
- previous_word = 0 ; Used for chaining the words
-
- IMMEDIATE = 1 ; optional flag (symbol)
-
-macro WORD label, name, doer, flags {
+;;; Macro WORD starts a FORTH word definition in this code.
+;;; The layout of a word is as follows:
+;;; TFA: [8 bytes] pointer to previous word in the word list
+;;; [8 bytes] pointer to the word's CFA
+;;; [8 bytes] a flags field
+;;; [8 bytes] the length of the word's pname
+;;; [varying] the word's pname
+;;; [1 byte] NUL -- making an asciiz of the pname
+;;; ;;[? bytes] 0-7 bytes for address alignment to [disabled]
+;;; [8 bytes] pointer to the word's TFA
+;;; OFF: [8 bytes] the DOES offset for the word
+;;; CFA: [8 bytes] pointer to the word's "doer" code
+;;; DFA: [? bytes] the word's data field
+
+IMMEDIATE = 1 ; optional flag (symbol)
+
+macro WORD label, name, doer, flags, previous, offset {
+ local pname
;; align 8
label#_TFA:
;; TFA
- dq previous_word
+ if previous eq
+ dq previous_word
+ else
+ dq previous
+ end if
previous_word = label#_TFA
;; PFA
+label#_pCFA:
+ dq label#_CFA ; link to CFA of word
+ dq flags + 0
label#_PFA:
- db flags + 0
- db label - $ - 2
+ dq pname - $ - 8
db name
- db 0
+pname: db 0 ; extra NUL byte
;; align 8
-
+label#_pTFA:
+ dq label#_TFA ; link to TFA of word
label#_OFF:
- dq 0 ; The DOES offset. Defaults to 0.
+ dq offset + 0 ; The DOES offset. Defaults to 0.
;; also CFA = pointer to "doer"
+label#_CFA:
label:
if doer eq
dq doforth
else
if doer in <fasm>
- dq label#_DFA
+ dq dofasm ; label#_DFA
else
dq doer
end if
label#_DFA:
}
+macro tfa2cfa reg {
+ mov reg,qword [reg+8]
+}
+macro tfa2does reg {
+ tfa2cfa reg
+ sub reg,8
+}
+macro tfa2dfa reg {
+ tfa2cfa reg
+ add reg,8
+}
+macro tfa2flags reg {
+ add reg,16
+}
+macro tfa2pfa reg {
+ add reg,24
+}
+macro tfa2pname reg {
+ add reg,32
+}
+macro cfa2tfa reg {
+ sub reg,16
+ mov reg,qword [reg]
+}
+macro cfa2dfa reg {
+ add reg,8
+}
+macro dfa2cfa reg {
+ sub reg,8
+}
+macro dfa2tfa reg {
+ sub reg,24
+ mov reg,qword [reg]
+}
+;;; Code snippet to push a pname string with address and 64-bit length field.
+;;; The register is advanced to point at the text part.
+macro pushpname reg {
+ add reg,8
+ push reg
+ push qword [reg-8]
+}
;;; ========================================
;;; The BLOCK macro lays out the length for a subsequent block to the
;;; given label.
}
;;; ========================================
-;;; The STRING macro lays out length byte and data for s short string
+;;; The STRING macro lays out length cell and data for several string
+;;; components.
macro STRING [data] {
common
local datastart, dataend
- db dataend - datastart
+ dq dataend - datastart
datastart:
forward
db data
dataend:
}
+;;; ========================================
+;;; The BRANCH macro lays out FORTH words BRANCH and 0BRANCH with offset
+macro BRANCH zero,label {
+ if zero in <0>
+ dq p_zero_branch
+ else
+ dq p_branch
+ end if
+ dq label - $ - 8
+}