// Defines a new pseudobuiltin, creating the word header and appropriate labels.
.macro pseudobuiltin label, name, flags=0
	.p2align 3
	forth.\label\().header:
		.quad last_pseudobuiltin
		.word (\flags << 8) | (forth.\label\().name.end - forth.\label\().name)
	forth.\label\().name:
		.ascii "\name"
	forth.\label\().name.end:
		.align 2, 0
		.byte forth.\label\().name.end - forth.\label\().name
		.skip 3
	.global forth.\label
	forth.\label:
		bl forth.__docolon
	.set last_pseudobuiltin, forth.\label\().header
.endm
.set last_pseudobuiltin, forth.__last_builtin.header

.set SMUDGED, 1
.set IMMEDIATE, 2

// Branches unconditionally.
.macro branch dest
	.quad forth.__branch, \dest
.endm

// ( x -- )
// Branches if x is zero.
.macro branch0 dest
	.quad forth.__branch0, \dest
.endm

// Embeds a reference to forth.exit.
.macro exit
	word exit
.endm

// Embeds a reference to a literal in a colon-defined word's PFA.
.macro lit num
	.quad forth.__lit, \num
.endm

// Embeds a reference to a word in a colon-defined word's PFA.
.macro word label
	.quad forth.\label
.endm

.section .text.forth.pseudobuiltins

pseudobuiltin _quote, "'"
	word parse_word
	word dup
	branch0 forth._quote.eof
	word find_word
	branch0 forth._quote.word_not_found
	word header_to_body
	exit
forth._quote.eof:
	word __unexpected_eof
forth._quote.word_not_found:
	word __word_not_found

// ( x1 x2 -- )
pseudobuiltin 2drop, "2DROP"
	word drop
	word drop
	exit

// ( x1 x2 -- x1 x2 x1 x2 )
pseudobuiltin 2dup, "2DUP"
	word over
	word over
	exit

// ( addr -- )
pseudobuiltin _comma_bl, "BL,"
	word here
	lit 4
	word allot
	word _bang_bl
	exit

pseudobuiltin create, "CREATE"
	word parse_word
	word dup
	branch0 forth.create.eof
	word create_str
	word exit

forth.create.eof:
	word __unexpected_eof

pseudobuiltin create_str, "CREATE-STR"
	lit 0xff
	word and

	lit 3
	word align_allot_pow2

	word latest
	word here
	word set_latest
	word _comma
	word dup
	lit 0x0100
	word or
	word _comma_w
	word dup
	word rot_rev
	word _comma_str

	lit 2
	word align_allot_pow2
	word _comma_w

	lit forth.__dovariable
	word _comma_bl
	exit

// ( -- addr len )
// reads from SOURCE
pseudobuiltin parse_word, "PARSE-WORD"
	word source
	word skip_spaces
	word set_source
	word source
	word drop
	word source
	word parse_word_from_str
	word dup
	word source
	word rot
	word adjust
	word set_source
	exit

pseudobuiltin __root_process, "", SMUDGED
forth.__root_process.loop:
	word parse_word
	word dup
	branch0 forth.__root_process.loop.end

	word 2dup
	word str_to_number
	branch0 forth.__root_process.loop.word
	word rot_rev
	word 2drop

	word state
	branch0 forth.__root_process.loop
	lit forth.__lit
	word _comma
	word _comma
	branch forth.__root_process.loop

forth.__root_process.loop.word:
	word drop
	word 2dup
	word find_word
	branch0 forth.__root_process.loop.word.not_found
	word rot_rev
	word 2drop
	word dup
	word header_to_body
	word swap

	word _is_immediate
	word invert
	word state
	word and
	branch0 forth.__root_process.loop.word.interpret
	word _comma
	branch forth.__root_process.loop

forth.__root_process.loop.word.interpret:
	word execute
	branch forth.__root_process.loop

forth.__root_process.loop.word.not_found:
	word drop
	word __word_not_found

forth.__root_process.loop.end:
	word 2drop
	lit forth.root_process_exited.msg
	lit forth.root_process_exited.msg.len
	word panic

.global forth.__last_pseudobuiltin.header
pseudobuiltin __last_pseudobuiltin, "", SMUDGED

.section .rodata.forth.pseudobuiltins

forth.root_process_exited.msg: .ascii "Root process exited!"
.set forth.root_process_exited.msg.len, . - forth.root_process_exited.msg

// vi: set ft=arm64asm :