SourceForge!
PFE 0.33.70


Homepage
SourceForge
Download
 
Documentation
-Overview
-The PFE Manual
  old manual / (book)
-ChangeLog
-Authors
-License (LGPL)  
-Wordsets / (book)
-Functions .. (book)
-Dp of ANS Forth
-The 4thTutor
-Forthprimer.pdf
-   Old Wordsets
-   Old Words List
 

Forth Links
* Forth Repository
* Taygeta Compilation
* TinyBoot FirmWare
* FiCL, Free Forth
* Research Vienna
* Research Bournemouth
* zForth WebRing
 

Other Links
* Tektronix/MPT
* Forth Org. (FIG)
* Forth Inc.
* MPE Ltd. Forths
* SF Win32Forth
* PD Win32Forth
* Neil Bawd
 

 

generated
(C) Guido U. Draheim
guidod@gmx.de

pfe Library Functions

Version 0.33.70

p4_asm_create_code --- : FCode
p4_asm_end_code --- : FCode
p4_block --- : FCode
p4_buffer --- : FCode
p4_save_buffers --- : FCode
p4_empty_buffers --- : FCode
p4_flush --- : FCode
p4_list --- : FCode
p4_load --- : FCode
p4_thru --- : FCode
p4_update --- : FCode
P4_LISTWORDS(block) = :
p4_close_blockfile --- : FCode
p4_open_blockfile --- : FCode
p4_create_blockfile --- : FCode
p4_zero_create_blockfile --- : FCode
p4_set_blockfile --- : FCode
p4_file_access(const p4_char_t *fn, int len) : _export int
p4_open_file(const p4_char_t *name, int len, int mode) : _export p4_File *
p4_create_file(const p4_char_t *name, int len, int mode) : _export p4_File *
p4_close_file(p4_File *fid) : _export int
p4_reposition_file(p4_File *fid, _p4_off_t pos) : _export int
p4_read_file(void *p, p4ucell *n, p4_File *fid) : _export int
p4_write_file(void *p, p4ucell n, p4_File *fid) : _export int
p4_resize_file(p4_File *fid, _p4_off_t size) : _export int
p4_read_line(void* buf, p4ucell *u, p4_File *fid, p4cell *ior) : _export int
p4_read_write(p4_File *fid, void *p, p4ucell n, int readflag) : _export void
p4_load_file(const p4_char_t *fn, int cnt, int blk) : _export void
p4_sh_else --- : FCode
p4_sh_endif --- : FCode
p4_sh_if --- : FCode
p4_sh_is_true --- : FCode
p4_sh_is_false --- : FCode
p4_sh_ifdef --- : FCode
p4_sh_ifnotdef --- : FCode
p4_backslash --- : extern FCode
p4_sh_define --- : FCode
p4_sh_pragma --- : FCode
p4_link_comma --- : FCode
p4_new_chain --- : FCode
p4_dot_chain --- : FCode
p4_dot_chains --- : FCode
p4_do_chain --- : FCode
p4_chain_add_before --- : FCode
p4_chain_add --- : FCode
p4_new_wordlist(p4char* nfa) : _export p4_Wordl*
p4_dot_words --- : FCode
p4_do_all_words --- : FCode
p4_redo_all_words --- : FCode
p4_do_all_words_while_loop --- : FCode
p4_do_all_words_while --- : FCode
p4_do_synonym --- : FCode
p4_alias_atexit --- : FCode
p4_do_alias --- : FCode
p4_z_fetch --- : FCode
p4_z_store --- : FCode
p4_x_fetch --- : FCode
p4_x_store --- : FCode
p4_y_fetch --- : FCode
p4_y_store --- : FCode
p4_z_dot --- : FCode
p4_z_s_dot --- : FCode
p4_real --- : FCode
p4_imag --- : FCode
p4_conjg --- : FCode
p4_z_drop --- : FCode
p4_z_dup --- : FCode
p4_z_swap --- : FCode
p4_z_over --- : FCode
p4_z_nip --- : FCode
p4_z_tuck --- : FCode
p4_z_rot --- : FCode
p4_minus_z_rot --- : FCode
p4_z_plus --- : FCode
p4_z_minus --- : FCode
p4_z_star --- : FCode
p4_z_slash --- : FCode
p4_z_negate --- : FCode
p4_z_two_star --- : FCode
p4_z_two_slash --- : FCode
p4_i_star --- : FCode
p4_minus_i_star --- : FCode
p4_one_slash_z --- : FCode
p4_z_hat_two --- : FCode
p4_z_abs_hat_two --- : FCode
p4_z_hat_n --- : FCode
p4_x_plus --- : FCode
p4_x_minus --- : FCode
p4_y_plus --- : FCode
p4_y_minus --- : FCode
p4_z_star_f --- : FCode
p4_z_slash_f --- : FCode
p4_f_star_z --- : FCode
p4_f_slash_z --- : FCode
p4_z_star_i_star_f --- : FCode
p4_minus_i_star_z_slash_f --- : FCode
p4_i_star_f_star_z --- : FCode
p4_i_star_f_slash_z --- : FCode
p4_z_star_to_real --- : FCode
p4_z_star_to_imag --- : FCode
p4_z_abs --- : FCode
p4_z_box --- : FCode
p4_arg --- : FCode
p4_to_polar --- : FCode
p4_polar_from --- : FCode
p4_z_ssqs --- : FCode
p4_z_sqrt --- : FCode
p4_z_ln --- : FCode
p4_z_exp --- : FCode
p4_z_hat --- : FCode
p4_z_cosh --- : FCode
p4_z_sinh --- : FCode
p4_z_tanh --- : FCode
p4_z_coth --- : FCode
p4_z_cos --- : FCode
p4_z_sin --- : FCode
p4_z_tan --- : FCode
p4_z_cot --- : FCode
p4_z_acos --- : FCode
p4_z_acosh --- : FCode
p4_z_asin --- : FCode
p4_z_asinh --- : FCode
p4_z_atanh --- : FCode
p4_z_atan --- : FCode
p4_z_constant --- : FCode
p4_z_literal --- : FCode
p4_z_variable --- : FCode
p4_store --- : FCode
p4_sh --- : FCode
p4_sh_greater --- : FCode
p4_sh_s --- : FCode
p4_tick --- : FCode
p4_paren --- : FCode
p4_star --- : FCode
p4_star_slash --- : FCode
p4_star_slash_mod --- : FCode
p4_plus --- : FCode
p4_plus_store --- : FCode
p4_plus_loop_execution --- : FCode_XE
p4_plus_loop --- : FCode
p4_comma --- : FCode
p4_minus --- : FCode
p4_dot --- : FCode
p4_dot_quote_execution --- : FCode_XE
p4_dot_quote --- : FCode
p4_slash --- : FCode
p4_slash_mod --- : FCode
p4_zero_less --- : FCode
p4_zero_equal --- : FCode
p4_one_plus --- : FCode
p4_one_minus --- : FCode
p4_two_store --- : FCode
p4_two_star --- : FCode
p4_two_slash --- : FCode
p4_two_fetch --- : FCode
p4_two_drop --- : FCode
p4_two_dup --- : FCode
p4_two_over --- : FCode
p4_two_swap --- : FCode
p4_colon_RT --- : FCode_RT
p4_colon --- : FCode
p4_semicolon_execution --- : FCode_XE
p4_semicolon --- : FCode
p4_less_than --- : FCode
p4_less_sh --- : FCode
p4_equals --- : FCode
p4_greater_than --- : FCode
p4_to_body --- : FCode
p4_to_number --- : FCode
p4_to_r --- : FCode
p4_Q_dup --- : FCode
p4_fetch --- : FCode
p4_abs --- : FCode
p4_accept --- : FCode
p4_align --- : FCode
p4_aligned --- : FCode
p4_allot --- : FCode
p4_and --- : FCode
p4_begin --- : FCode
p4_c_store --- : FCode
p4_c_comma --- : FCode
p4_c_fetch --- : FCode
p4_cell_plus --- : FCode
p4_cells --- : FCode
p4_char --- : FCode
p4_char_plus --- : FCode
p4_chars --- : FCode
p4_constant_RT --- : FCode_RT
p4_constant --- : FCode
p4_count --- : FCode
p4_cr --- : FCode
p4_decimal --- : FCode
p4_depth --- : FCode
p4_do_execution --- : FCode_XE
p4_do --- : FCode
p4_variable_RT --- : FCode_RT
p4_builds_RT --- : FCode
p4_does_RT --- : FCode_RT
p4_does_execution --- : FCode_XE
p4_does --- : FCode
p4_builds --- : FCode
p4_drop --- : FCode
p4_dup --- : FCode
p4_branch_execution --- : FCode_XE
p4_else_execution --- : FCode_XE
p4_else --- : FCode
p4_emit --- : FCode
p4_environment_Q_core --- : FCode
p4_evaluate --- : FCode
p4_execute --- : FCode
p4_exit --- : FCode
p4_fill --- : FCode
p4_find --- : FCode
p4_f_m_slash_mod --- : FCode
p4_here --- : FCode
p4_hold --- : FCode
p4_i --- : FCode
p4_q_branch_execution --- : FCode_XE
p4_if_execution --- : FCode_XE
p4_if --- : FCode
p4_immediate --- : FCode
p4_invert --- : FCode
p4_j --- : FCode
p4_key --- : FCode
p4_leave --- : FCode
p4_literal_execution --- : FCode_XE
p4_literal --- : FCode
p4_loop_execution --- : FCode_XE
p4_loop --- : FCode
p4_l_shift --- : FCode
p4_m_star --- : FCode
p4_max --- : FCode
p4_min --- : FCode
p4_mod --- : FCode
p4_move --- : FCode
p4_negate --- : FCode
p4_or --- : FCode
p4_over --- : FCode
p4_postpone_execution --- : FCode_XE
p4_postpone --- : FCode
p4_quit --- : FCode
p4_r_from --- : FCode
p4_r_fetch --- : FCode
p4_recurse --- : FCode
p4_repeat --- : FCode
p4_rot --- : FCode
p4_r_shift --- : FCode
p4_s_quote_execution --- : FCode_XE
p4_s_quote --- : FCode
p4_s_to_d --- : FCode
p4_sign --- : FCode
p4_s_m_slash_rem --- : FCode
p4_source --- : FCode
p4_space --- : FCode
p4_spaces --- : FCode
p4_swap --- : FCode
p4_then --- : FCode
p4_type --- : FCode
p4_u_dot --- : FCode
p4_u_less_than --- : FCode
p4_u_m_star --- : FCode
p4_u_m_slash_mod --- : FCode
p4_unloop --- : FCode
p4_until --- : FCode
p4_variable --- : FCode
p4_while --- : FCode
p4_word --- : FCode
p4_xor --- : FCode
p4_left_bracket --- : FCode
p4_bracket_tick --- : FCode
p4_bracket_char --- : FCode
p4_right_bracket --- : FCode
p4_dot_paren --- : FCode
p4_dot_r --- : FCode
p4_zero_not_equals --- : FCode
p4_zero_greater --- : FCode
p4_two_to_r --- : FCode
p4_two_r_from --- : FCode
p4_two_r_fetch --- : FCode
p4_colon_noname_RT --- : FCode_RT
p4_colon_noname --- : FCode
p4_not_equals --- : FCode
p4_Q_do_execution --- : FCode_XE
p4_Q_do --- : FCode
p4_again --- : FCode
p4_c_quote_execution --- : FCode_XE
p4_c_quote --- : FCode
p4_case --- : FCode
p4_compile_comma --- : FCode
p4_convert --- : FCode
p4_endcase --- : FCode
p4_endof --- : FCode
p4_erase --- : FCode
p4_expect --- : FCode
p4_hex --- : FCode
p4_marker --- : FCode
p4_nip --- : FCode
p4_of_execution --- : FCode_XE
p4_of --- : FCode
p4_pad --- : FCode
p4_parse --- : FCode
p4_parse_word --- : FCode
p4_pick --- : FCode
p4_refill --- : FCode
p4_restore_input --- : FCode
p4_roll --- : FCode
p4_save_input --- : FCode
p4_to_execution --- : FCode_XE
p4_to --- : FCode
p4_tuck --- : FCode
p4_u_dot_r --- : FCode
p4_u_greater_than --- : FCode
p4_unused --- : FCode
p4_value_RT --- : FCode_RT
p4_value --- : FCode
p4_within --- : FCode
p4_bracket_compile --- : FCode
p4_quote --- : FCode
p4_zero_less_equal --- : FCode
p4_zero_greater_equal --- : FCode
p4_less_equal --- : FCode
p4_greater_equal --- : FCode
p4_u_less_equal --- : FCode
p4_u_greater_equal --- : FCode
p4_u_max --- : FCode
p4_u_min --- : FCode
p4_license --- : FCode
p4_warranty --- : FCode
p4_dot_version --- : FCode
p4_dot_date --- : FCode
p4_string_comma --- : FCode
p4_parse_comma --- : FCode
p4_parse_comma_quote --- : FCode
p4_paren_marker --- : FCode
p4_anew --- : FCode
p4_marker_RT --- : FCode_RT
p4_strpush(const char *s) : _export void
p4_pocket(void) : _export P4_GCC_MALLOC void*
p4_dash_trailing(p4_char_t *s, int n) : _export P4_GCC_WARN_UNUSED_RESULT int
p4_lower(p4_char_t *p, int n) : _export void
p4_upper(p4_char_t *p, int n) : _export void
p4_store_c_string(const p4_char_t *src, int n, char *dst, int max) : _export char*
p4_pocket_c_string(const p4_char_t* src, int n) : _export P4_GCC_MALLOC char*
p4_store_filename(const p4_char_t* str, int n, char* dst, int max) : _export char*
p4_pocket_filename(const p4_char_t* src, int n) : _export P4_GCC_MALLOC char*
p4_search(const char *p1, int u1, const char *p2, int u2) : _export char *
p4_match(const p4char *pattern, const p4char *str, int len, int ic) : _export int
p4_udiv(p4ucell num, p4ucell denom) : _export P4_GCC_CONST udiv_t
p4_fdiv(p4cell num, p4cell denom) : _export P4_GCC_CONST fdiv_t
p4_u_d_div(p4udcell *ud, p4ucell denom) : _export p4ucell
p4_u_d_mul(p4udcell *ud, p4ucell w, p4ucell c) : _export void
p4_dig2num(p4_char_t c, p4ucell *n, p4ucell base) : _export int
p4_num2dig(p4ucell n) : _export P4_GCC_CONST char
p4_number_question(const p4_char_t *p, p4ucell n, p4dcell *d) : _export int
p4_str_ud_dot_r(p4udcell ud, char *p, int w, int base) : _export char *
p4_str_d_dot_r(p4dcell d, char *p, int w, int base) : _export char *
p4_str_dot(p4cell n, char *p, int base) : _export char *
p4_outc(char c) : _export void
p4_outf(const char *s,...) : int
p4_type_on_line(const p4_char_t *str, p4cell len) : _export void
p4_emits(int n, const char c) : _export void
p4_tab(int n) : _export void
p4_dot_line(p4_File *fid, p4cell n, p4cell l) : _export void
p4_query --- : FCode
p4_next_line(void) : _export p4_bool_t
p4_size_saved_input(void) : _export p4ucell
p4_link_saved_input(void *p) : _export void
p4_unlink_saved_input(void *p) : _export void
p4_skip_delimiter(char del) : _export void
p4_word_parse(char del) : _export p4_cell_t
p4_word_to_here(void) : _export char*
p4_debug --- : FCode
p4_no_debug --- : FCode
p4_paren_see --- : FCode
p4_addr_to_name(const p4_byte_t* addr) : _export p4_namebuf_t const *
p4_come_back --- : FCode
p4_make_wordlist(p4char* nfa) : _export p4_Wordl *
p4_forget_dp --- : FCode
p4_forget(p4_byte_t* above) : _export void
p4_forget_word(const char *name, p4cell id, p4code ccode, p4cell what) : _export p4_namebuf_t*
p4_tick_nfa(void) : _export p4char *
p4_tick_cfa(void) : _export p4xt
p4_only_RT --- : FCode
p4_forth_RT --- : FCode
p4_dlinit(void) : _export int
p4_dlerror(void) : _export const char*
p4_dlopenext(const char* name) : _export void*
p4_dlclose(const void* lib) : _export int
p4_dlsym(const void* lib, const char* symbol) : _export void*
p4_dladdr(void* addr, int* offset) : _export char*
p4_slot_use(int* var) : int
p4_slot_unuse(int* var) : int
p4_paren_loadm --- : FCode
p4_loadm --- : FCode
p4_local_dlsym --- : FCode
p4_local_dlcall --- : FCode
p4_lt_dlinit --- : FCode
p4_lt_dlopenext --- : FCode
p4_lt_dlsym --- : FCode
p4_lt_dlcose --- : FCode
p4_lt_dlerror --- : FCode
p4_two_constant_RT --- : FCode_RT
p4_two_constant --- : FCode
p4_two_literal_execution --- : FCode_XE
p4_two_literal --- : FCode
p4_two_variable --- : FCode
p4_d_plus --- : FCode
p4_d_minus --- : FCode
p4_d_dot_r --- : FCode
p4_d_dot --- : FCode
p4_d_zero_less --- : FCode
p4_d_zero_equals --- : FCode
p4_d_two_star --- : FCode
p4_d_two_slash --- : FCode
p4_d_less --- : FCode
p4_d_to_s --- : FCode
p4_d_equals --- : FCode
p4_d_abs --- : FCode
p4_d_max --- : FCode
p4_d_min --- : FCode
p4_d_negate --- : FCode
p4_m_star_slash --- : FCode
p4_m_plus --- : FCode
p4_two_rot --- : FCode
p4_d_u_less --- : FCode
p4_literal_comma --- : FCode
p4_two_literal_comma --- : FCode
p4_dcells --- : FCode
p4_d_shiftleft --- : FCode
p4_d_shiftright --- : FCode
p4_um_plus(p4dcell * a, p4ucell b) : _export void
p4_d_ummul(p4ucell a, p4ucell b) : _export p4udcell
p4_d_mmul(p4cell a, p4cell b) : _export p4dcell
p4_d_umdiv(p4udcell num, p4ucell denom) : _export udiv_t
p4_d_smdiv(p4dcell num, p4cell denom) : _export fdiv_t
p4_d_fmdiv(p4dcell num, p4cell denom) : _export fdiv_t
p4_empty_str --- : FCode
p4_newline_str --- : FCode
p4_parens_m_store --- : FCode
p4_parse_to_s --- : FCode
p4_s_back_tick --- : FCode
p4_m_comma_s --- : FCode
p4_m_count_fetch --- : FCode
p4_m_count_store --- : FCode
p4_m_count --- : FCode
p4_minus_m_count --- : FCode
p4_zero_strings --- : FCode
p4_str_garbage_Q --- : FCode
p4_str_gc_off --- : FCode
p4_str_gc_on --- : FCode
p4_str_gc_lock_fetch --- : FCode
p4_str_gc_lock_store --- : FCode
p4_str_unused --- : FCode
p4_collect_str_garbage --- : FCode
p4_make_str_space --- : FCode
p4_slash_str_buf --- : FCode
p4_max_num_str_frames --- : FCode
p4_str_store --- : FCode
p4_str_fetch --- : FCode
p4_str_quote --- : FCode
p4_str_back_tick --- : FCode
p4_str_constant --- : FCode
p4_str_variable --- : FCode
p4_parse_to_str --- : FCode
p4_str_two_drop --- : FCode
p4_str_two_dup --- : FCode
p4_str_depth --- : FCode
p4_str_drop --- : FCode
p4_str_dup --- : FCode
p4_str_nip --- : FCode
p4_str_over --- : FCode
p4_str_pick --- : FCode
p4_str_swap --- : FCode
p4_str_exchange --- : FCode
p4_str_s_from --- : FCode
p4_str_comma_s --- : FCode
p4_str_s_fetch --- : FCode
p4_str_tuck --- : FCode
p4_to_str_s --- : FCode
p4_to_str_s_copy --- : FCode
p4_str_plus --- : FCode
p4_parse_s_plus --- : FCode
p4_endcat --- : FCode
p4_str_plus_quote --- : FCode
p4_str_plus_back_tick --- : FCode
p4_num_str_args --- : FCode
p4_str_args_brace --- : FCode
p4_str_frame --- : FCode
p4_str_frame_depth --- : FCode
p4_drop_str_frame --- : FCode
p4_find_str_arg --- : FCode
p4_th_str_arg --- : FCode
p4_do_drop_str_frame --- : FCode
p4_str_pop --- : FCode
p4_str_push_ext --- : FCode
p4_str_breakp_fetch --- : FCode
p4_str_bufp_fetch --- : FCode
p4_str_fbreakp_fetch --- : FCode
p4_str_fsp0_fetch --- : FCode
p4_str_fsp_fetch --- : FCode
p4_str_sp0_fetch --- : FCode
p4_str_sp_fetch --- : FCode
p4_slash_str_frame_item --- : FCode
p4_slash_str_frame_stack --- : FCode
p4_slash_str_space_header --- : FCode
p4_zero_str_space --- : FCode
p4_cat_str_p_fetch --- : FCode
p4_in_str_buffer_Q --- : FCode
p4_edit_block --- : FCode
p4_edit_text --- : FCode
p4_edit_error --- : FCode
p4_Exec(p4_threadP th) : _export int
p4_call_stop --- : FCode_XE
p4_call_loop(p4xt xt) : _export void
p4_call(p4xt xt) : _export void
p4_normal_execute(p4xt xt) : _export void
p4_simple_execute(p4xt xt) : _export void
p4_interpret --- : FCode
p4_include_file(p4_File *fid) : _export void
p4_included1(const p4_char_t *name, int len, int throws) : _export int
p4_included(const p4_char_t* name, int len) : _export void
p4_closeall_files --- : FCode
p4_ok --- : FCode
p4_interpret_loop(P4_VOID) : _export int
p4_cold_system --- : FCode
p4_boot_system --- : FCode
p4_include_required --- : FCode
p4_include_require --- : FCode
p4_environment --- : FCode
p4_environment_Q(const p4_char_t* str, p4cell l) : _export p4_char_t*
p4_needs_environment --- : FCode
p4_catch --- : FCode
p4_throw --- : FCode
p4_abort --- : FCode
p4_abort_quote_execution --- : FCode_XE
p4_abort_quote --- : FCode
p4_exception_string --- : FCode
p4_longjmp_loop(int arg) : _export void
p4_throws(int id, const p4_char_t* description, int len) : _export void
p4_at_x_y --- : FCode
p4_key_question --- : FCode
p4_ekey --- : FCode
p4_ekey_to_char --- : FCode
p4_ekey_question --- : FCode
p4_emit_question --- : FCode
p4_ms --- : FCode
p4_time_and_date --- : FCode
p4_dot_clrscr --- : extern FCode
p4_ignore_line --- : FCode
p4_clock_fetch --- : FCode
p4_bin --- : FCode
p4_delete_file --- : FCode
p4_file_position --- : FCode
p4_file_size --- : FCode
p4_write_line --- : FCode
p4_file_status --- : FCode
p4_flush_file --- : FCode
p4_rename_file --- : FCode
p4_include --- : FCode
p4_copy_file --- : FCode
p4_move_file --- : FCode
p4_file_rw --- : FCode
p4_file_block --- : FCode
p4_file_buffer --- : FCode
p4_file_empty_buffers --- : FCode
p4_file_flush --- : FCode
p4_file_list --- : FCode
p4_file_load --- : FCode
p4_file_save_buffers --- : FCode
p4_file_thru --- : FCode
p4_file_update --- : FCode
p4_dfaligned(p4cell n) : _export p4cell
p4_to_float(const p4_char_t *p, p4cell n, double *r) : _export int
p4_f_to_d --- : FCode
p4_f_p_fetch --- : FCode
p4_f_p_store --- : FCode
p4_f_equal --- : FCode
p4_f_not_equal --- : FCode
p4_s_to_f --- : FCode
p4_f_trunc_to_s --- : FCode
p4_f_round_to_s --- : FCode
p4_f_trunc --- : FCode
p4_minus_f_rot --- : FCode
p4_f_nip --- : FCode
p4_f_tuck --- : FCode
p4_one_over_f --- : FCode
p4_f_square --- : FCode
p4_f_power_n --- : FCode
p4_f_two_slash --- : FCode
p4_f_two_star --- : FCode
p4_f_zero_greater --- : FCode
p4_f_zero_not_equal --- : FCode
p4_two_plus --- : FCode
p4_two_minus --- : FCode
p4_compile --- : FCode
p4_vocabulary_RT --- : FCode_RT
p4_vocabulary --- : FCode
p4_next_block --- : FCode
p4_k --- : FCode
p4_octal --- : FCode
p4_s_p_fetch --- : FCode
p4_store_bits --- : FCode
p4_power --- : FCode
p4_byte_swap --- : FCode
p4_byte_swap_move --- : FCode
p4_fetch_bits --- : FCode
p4_seal --- : FCode
p4_c_plus_store --- : FCode
p4_to_wordlist --- : FCode
p4_bounds --- : FCode
p4_off_store --- : FCode
p4_on_store --- : FCode
p4_append --- : FCode
p4_append_char --- : FCode
p4_place --- : FCode
p4_question_leave --- : FCode
p4_noop --- : extern FCode
p4_r_p_fetch --- : FCode
p4_r_p_store --- : FCode
p4_s_p_store --- : FCode
p4_dash_rot --- : FCode
p4_c_set --- : FCode
p4_c_reset --- : FCode
p4_c_toggle --- : FCode
p4_toggle --- : FCode
p4_three_dup --- : FCode
p4_three_drop --- : FCode
p4_four_dup --- : FCode
p4_four_drop --- : FCode
p4_toupper --- : FCode
p4_ascii --- : FCode
p4_control --- : FCode
p4_vocs --- : FCode
p4_fetch_execute --- : FCode
p4_file_check --- : FCode
p4_memory_check --- : FCode
p4_plus_plus --- : FCode
p4_fetch_plus_plus --- : FCode
p4_store_plus_plus --- : FCode
p4_nofp_dfaligned(p4cell n) : _export p4cell
p4_nofp_to_float(const p4_char_t *p, p4cell n, double *r) : _export int
p4_nofp_s_to_f --- : FCode
p4_nofp_f_trunc_to_s --- : FCode
p4_nofp_f_round_to_s --- : FCode
p4_nofp_f_trunc --- : FCode
p4_nofp_minus_f_rot --- : FCode
p4_nofp_f_nip --- : FCode
p4_nofp_f_tuck --- : FCode
p4_nofp_one_over_f --- : FCode
p4_nofp_f_square --- : FCode
p4_nofp_f_power_n --- : FCode
p4_nofp_f_two_slash --- : FCode
p4_nofp_f_two_star --- : FCode
p4_nofp_f_zero_greater --- : FCode
p4_nofp_f_zero_not_equal --- : FCode
p4_gforth_open_dir --- : FCode
p4_gforth_read_dir --- : FCode
p4_gforth_close_dir --- : FCode
p4_gforth_linked --- : FCode
p4_gforth_chained --- : FCode
p4_gforth_chainperform --- : FCode
p4_to_name --- : FCode
p4_to_link --- : FCode
p4_body_from --- : FCode
p4_name_from --- : FCode
p4_link_from --- : FCode
p4_l_to_name --- : FCode
p4_n_to_link --- : FCode
p4_to_ffa --- : FCode
p4_ffa_from --- : FCode
p4_name_to_string --- : FCode
p4_header_comma --- : FCode
p4_str_header --- : FCode
p4_latest --- : FCode
p4_smudge --- : FCode
p4_hide --- : FCode
p4_reveal --- : FCode
p4_name_flags_fetch --- : FCode
p4_name_flags_store --- : FCode
p4_defer_RT --- : FCode
p4_defer --- : FCode
p4_is --- : FCode
p4_action_of --- : FCode
p4_defer_store --- : FCode
p4_defer_fetch --- : FCode
p4_alias --- : FCode
p4_synonym_RT --- : FCode_RT
p4_obsoleted_RT --- : FCode_RT
p4_synonym --- : FCode
p4_obsoleted --- : FCode
p4_deprecated --- : FCode
p4_check_deprecated --- : FCode
p4_extern_deprecated --- : FCode
p4_logmessage --- : FCode
p4_dictvar_RT --- : FCode_RT
p4_dictget_RT --- : FCode_RT
p4_paren_help --- : FCode
p4_open_terminal_logfile --- : FCode
p4_close_terminal_logfile --- : FCode
p4_terminal_answer_link --- : FCode
p4_terminal_output_link --- : FCode
p4_terminal_input_link --- : FCode
p4_terminal_emulation_state --- : FCode
p4_paren_local --- : FCode
p4_locals_bar --- : FCode
p4_local_value --- : FCode
p4_local_buffer_var --- : FCode
p4_emu_sendme_command(k12_emu_type_t* emul_id, const u8_t* str, int len) : status_t
p4_allocate --- : FCode
p4_free --- : FCode
p4_resize --- : FCode
p4_dict_allocate(int items, int size, int align, void** lower, void** upper) : _export void*
p4_cold --- : FCode
p4_u_d_dot_r --- : FCode
p4_u_d_dot --- : FCode
p4_id_dot --- : FCode
p4_dash_roll --- : FCode
p4_random --- : FCode
p4_srand --- : FCode
p4_plus_under --- : FCode
p4_under_plus --- : FCode
p4_plus_to_execution --- : FCode_XE
p4_plus_to_local_execution --- : FCode_XE
p4_plus_to --- : FCode
p4_build_array --- : FCode
p4_access_array --- : FCode
p4_source_line --- : FCode
p4_source_name --- : FCode
p4_th_pocket --- : FCode
p4_pocket_pad --- : FCode
p4_wl_hash --- : FCode
p4_topmost --- : FCode
p4_ls_words --- : FCode
p4_ls_primitives --- : FCode
p4_ls_cdefs --- : FCode
p4_ls_ddefs --- : FCode
p4_ls_constants --- : FCode
p4_ls_variables --- : FCode
p4_ls_vocabularies --- : FCode
p4_ls_markers --- : FCode
p4_w_fetch --- : FCode
p4_w_store --- : FCode
p4_w_plus_store --- : FCode
p4_backspace --- : FCode
p4_Q_stop --- : FCode
p4_start_Q_cr --- : FCode
p4_Q_cr --- : FCode
p4_close_all_files --- : FCode
p4_dot_memory --- : FCode
p4_dot_status --- : FCode
p4_paren_emit --- : FCode
p4_paren_expect --- : FCode
p4_paren_key --- : FCode
p4_paren_type --- : FCode
p4_standard_io --- : FCode
p4_executes_execution --- : FCode_XE
p4_executes --- : FCode
p4_help --- : FCode
p4_edit_blockfile --- : FCode
p4_argc --- : FCode
p4_argv --- : FCode
p4_expand_fn --- : FCode
p4_load_quote_execution --- : FCode_XE
p4_load_quote --- : FCode
p4_system --- : FCode
p4_system_quote_execution --- : FCode_XE
p4_system_quote --- : FCode
p4_create_var --- : FCode
p4_buffer_var --- : FCode
p4_r_tick_fetch --- : FCode
p4_r_tick_store --- : FCode
p4_r_quote_fetch --- : FCode
p4_r_quote_store --- : FCode
p4_r_store --- : FCode
p4_two_r_store --- : FCode
p4_dup_to_r --- : FCode
p4_r_from_drop --- : FCode
p4_two_r_from_drop --- : FCode
p4_clearstack --- : FCode
_p4_access(const char *fn, int how) : int
_p4_rename(const char *source, const char *target) : int
p4_module --- : FCode
p4_end_module --- : FCode
p4_export --- : FCode
p4_expose_module --- : FCode
p4_also_module --- : FCode
p4_nvram_words --- : FCode
p4_nvram_as --- : FCode
p4_nvram_to --- : FCode
p4_nvram_z_fetch --- : FCode
p4_nvram_s_fetch --- : FCode
p4_nvram_Q_fetch --- : FCode
p4_SetOptionsDefault(p4_sessionP set, int len) : _export void
p4_AddOptions(p4_sessionP set, int argc, const char** argv) : _export int
p4_SetOptions(p4_sessionP set, int len, int argc, const char** argv) : _export int
p4_FreeOptions(int returncode, p4_sessionP set) : _export int
p4_SetModules(p4_sessionP set, p4Words* modules) : _export int
p4_gettimeofday(p4ucell* sec, p4ucell* usec) : _export void
p4_ntohs --- : FCode
p4_ntohl --- : FCode
p4_definitions --- : FCode
p4_get_current --- : FCode
p4_get_order --- : FCode
p4_search_wordlist --- : FCode
p4_set_current --- : FCode
p4_set_order --- : FCode
p4_wordlist --- : FCode
p4_also --- : FCode
p4_order --- : FCode
p4_previous --- : FCode
p4_default_order --- : FCode
p4_reset_order --- : FCode
p4_search_init --- : FCode
p4_getpid --- : FCode
p4_getuid --- : FCode
p4_geteuid --- : FCode
p4_getgid --- : FCode
p4_umask --- : FCode
p4_home --- : FCode
p4_user --- : FCode
p4_cwd --- : FCode
p4_pwd --- : FCode
p4_chdir --- : FCode
p4_install_signal_handlers(void) : _export void
p4_swap_signals(void) : _export void
p4_forth_signal(int sig, p4xt xt) : _export p4xt
p4_load_signals(p4_Wordl *wid) : _export void
p4_raise --- : FCode
p4_raise_signal --- : FCode
p4_smart_interpret_char(char c) : p4xt
_p4_smart_interpret_init(char c, char const * nm, int l) : p4_char_t*
p4_smart_interpret_init(char c, char const * nm, int l) : void
p4_smart_interpret_store --- : FCode
p4_narrow_changer --- : FCode
p4_narrow_inputlist --- : FCode
p4_narrow_outputlist --- : FCode
p4_narrow_input_variant --- : FCode
p4_narrow_output_variant --- : FCode
p4_narrow_input_stack --- : FCode
p4_narrow_output_stack --- : FCode
p4_narrow_input_argument --- : FCode
p4_narrow_output_argument --- : FCode
p4_narrow_input_argument_name --- : FCode
p4_narrow_output_argument_name --- : FCode
p4_narrow_input_argument_type --- : FCode
p4_narrow_output_argument_type --- : FCode
p4_canonic_input_type --- : FCode
p4_canonic_output_type --- : FCode
p4_rewriter_test --- : FCode
p4_rewriter_input_arg --- : FCode
p4_rewrite_line --- : FCode
p4_rewrite_show --- : FCode
p4_rewrite_stack_test --- : FCode
p4_rewrite_input_arg --- : FCode
p4_rewrite_stack_result --- : FCode
p4_narrow_input_notation --- : FCode
p4_narrow_output_notation --- : FCode
p4_rewrite_stackdef_test --- : FCode
p4_rewrite_stackdef_result --- : FCode
p4_rewrite_test --- : FCode
p4_narrow_inputdef_for_stackdef(pair_t inputlist, pair_t stackdef) : int
p4_find_stackhelp_body(const p4_char_t* word, p4cell len) : stackhelp_body*
p4_stackhelpcomment --- : FCode
p4_stackhelps(void) : void
p4_stackhelp --- : FCode
p4_stackhelp_execute_procs(const char* str, const char* end) : int
p4_search_stackhelp(word, len) : ___ p4char* nfa =
p4_slash_string --- : FCode
p4_blank --- : FCode
p4_cmove --- : FCode
p4_cmove_up --- : FCode
p4_compare --- : FCode
p4_sliteral --- : FCode
p4_field --- : FCode
p4_sizeof_XT --- : FCode_XE
p4_structure_RT --- : FCode_RT
p4_endstructure --- : FCode
p4_struct --- : FCode
p4_end_struct --- : FCode
p4_subrecord --- : FCode
p4_end_subrecord --- : FCode
p4_array_of --- : FCode
p4_variant --- : FCode
p4_end_variant --- : FCode
p4_instance --- : FCode
p4_instance_addr --- : FCode
p4_backward_mark --- : FCode
p4_backward_resolve --- : FCode
p4_forward_mark --- : FCode
p4_forward_resolve --- : FCode
p4_branch --- : FCode
p4_q_branch --- : FCode
p4_termcatch --- : FCode
p4_show_control_strings --- : FCode
p4_show_rawkey_strings --- : FCode
p4_show_termcap --- : FCode
p4_assume_vt100 --- : FCode
p4_assume_dumbterm --- : FCode
p4_gotoxy --- : FCode
p4_question_xy --- : FCode
p4_ekey_to_fkey --- : FCode
p4_defined --- : extern FCode
p4_undefined --- : extern FCode
p4_empty --- : FCode
p4_third --- : FCode
p4_fourth --- : FCode
p4_two_nip --- : FCode
p4_andif --- : FCode
p4_orif --- : FCode
p4_scan --- : FCode
p4_skip --- : FCode
p4_back --- : FCode
p4_div_split --- : FCode
p4_is_white --- : FCode
p4_trim --- : FCode
p4_bl_scan --- : FCode
p4_bl_skip --- : FCode
p4_starts_Q --- : FCode
p4_ends_Q --- : FCode
p4_is_digit --- : FCode
p4_is_alpha --- : FCode
p4_is_alnum --- : FCode
p4_split_next_line --- : FCode
p4_view_next_line --- : FCode
p4_next_word --- : FCode
p4_lexeme --- : FCode
p4_h_sh --- : FCode
p4_backslash_backslash --- : FCode
p4_tick_th --- : FCode
p4_paren_dot --- : FCode
p4_cell_minus --- : FCode
p4_hiword --- : FCode
p4_loword --- : FCode
p4_rewind_file --- : FCode
p4_dot_s --- : FCode
p4_question --- : FCode
p4_dump --- : FCode
p4_see --- : FCode
p4_words --- : FCode
p4_new_ahead --- : FCode
p4_bye --- : FCode
p4_cs_pick --- : FCode
p4_cs_roll --- : FCode
p4_bracket_else --- : FCode
p4_bracket_if --- : FCode
p4_assembler --- : FCode
p4_create_code --- : FCode
p4_semicolon_code_execution --- : FCode_XE
p4_end_code --- : FCode
p4_vlist --- : FCode
p4_store_csp --- : FCode
p4_Q_csp --- : FCode
p4_Q_comp --- : FCode
p4_Q_exec --- : FCode
p4_Q_file --- : FCode
p4_Q_loading --- : FCode
p4_Q_pairs --- : FCode
p4_Q_stack --- : FCode
p4_paren_forget --- : FCode
p4_paren_dictlimit --- : FCode
p4_paren_dictfence --- : FCode
p4_Q_file_open(p4_File *fid) : _export void
p4_abortq(const char *fmt,...) : _export void
p4_to_compile(p4xt xt) : void
p4_prefix_begin --- : FCode
p4_prefix_end --- : FCode
p4_prefix_end_doubled --- : FCode
p4_sprintf --- : FCode
p4_printf --- : FCode
p4_loadf --- : FCode
p4_paren_loadf_locate --- : FCode
p4_loadf_locate --- : FCode
p4_semicolon_and_execution --- : FCode_XE
p4_semicolon_and --- : FCode
p4_make_to_local_execution --- : FCode_XE
p4_make_to_execution --- : FCode_XE
p4_make --- : FCode
p4_offset_RT --- : FCode_RT
p4_offset_constant --- : FCode
p4_plus_field --- : FCode
p4_slash_field --- : FCode
p4_bracket_not --- : FCode
p4_replace_in --- : FCode
p4_x_quote --- : FCode
p4_evaluate_with --- : FCode
p4_bracket_vocabulary --- : FCode
p4_bracket_possibly --- : FCode
p4_bracket_def --- : FCode
p4_context_Q --- : FCode
p4_defs_are_case_sensitive --- : FCode
p4_case_sensitive_voc --- : FCode
p4_defs_are_searched_also --- : FCode
p4_bracket_execute --- : FCode
p4_spy_on --- : FCode
p4_spy_off --- : FCode
p4_spy_colon_RT --- : FCode_RT
p4_spy_colon --- : FCode
p4_spy_semicolon --- : FCode
p4_spy_exit --- : FCode
p4_tick_from --- : FCode
p4_fetch_from --- : FCode
p4_into_execution --- : FCode_XE
p4_into_local_execution --- : FCode_XE
p4_into --- : FCode
p4_dot_h2 --- : FCode
p4_here_word --- : FCode
p4_z_quote --- : FCode
p4_zcount --- : FCode
p4_zstrlen --- : FCode
p4_zmove --- : FCode
p4_appendz --- : FCode
p4_zplace --- : FCode
p4_c_backslash_quote --- : FCode
p4_s_backslash_quote --- : FCode
p4_z_backslash_quote --- : FCode

Documentation

p4_asm_create_code --- : FCode
CODE ( "name" -- ) pfe/assembler-ext.c

call ALSO and add ASSEMBLER wordlist if available. Add PROC ENTER assembler snippet as needed for the architecture into the PFA. The CFA is setup (a) with the PFA adress in traditional ITC or (b) with an infoblock as for sbr-coded colon words.

Remember that not all architectures are support and that the ASSEMBLER wordset is not compiled into pfe by default. Use always the corresponding END-CODE for each CODE start. The new word name is not smudged.

p4_asm_end_code --- : FCode
END-CODE ( "name" -- ) pfe/assembler-ext.c

call PREVIOUS and add PROC LEAVE assembler snippet as needed for the architecture - usually includes bits to "return from subroutine". Remember that not all architectures are support and PFE usually does only do variants of call-threading with a separate loop for the inner interpreter that does "call into subroutine". Some forth implementations do "jump into routine" and the PROC LEAVE part would do "jump to next routine" also known as next-threading. The sbr-call-threading is usually similar to the native subroutine-coding of the host operating system. See CODE

p4_block --- : FCode
BLOCK ( block-u -- block-addr ) [ANS] pfe/block-ext.c

load the specified block into a block buffer and return the address of that block buffer - see also BUFFER

p4_buffer --- : FCode
BUFFER ( block-u -- block-addr ) [ANS] pfe/block-ext.c

get the block buffer address for the specified block - if it had not been loaded already it is not filled with data from the disk unlike BLOCK does.

p4_save_buffers --- : FCode
SAVE-BUFFERS ( -- ) [ANS] pfe/block-ext.c

write all modified buffer to the disk, see UPDATE and FLUSH

p4_empty_buffers --- : FCode
EMPTY-BUFFERS ( -- ) [ANS] pfe/block-ext.c

unassign all block buffers, does not even UPDATE

p4_flush --- : FCode
FLUSH ( -- ) [ANS] pfe/block-ext.c

call SAVE-BUFFERS and then unassign all block buffers with EMPTY-BUFFERS

p4_list --- : FCode
LIST ( block-u -- ) [ANS] pfe/block-ext.c

display the block

p4_load --- : FCode
LOAD ( block-u -- ?? ) [FORTH] pfe/block-ext.c

INTERPRET the specified BLOCK

p4_thru --- : FCode
THRU ( block1-u block2-u -- ) [ANS] pfe/block-ext.c

LOAD a number of block in sequence.

p4_update --- : FCode
UPDATE ( -- ) [ANS] pfe/block-ext.c

mark the current block buffer as modified, see FLUSH

P4_LISTWORDS(block) = :
  pfe/block-ext.c
p4_close_blockfile --- : FCode
CLOSE-BLOCKFILE ( -- ) [FTH] w32for pfe/block-mix.c

w32for-implementation:

  blockhandle -1 <> if flush close-file drop then
  -1 set-blockfile

in pfe:

  : CLOSE-BLOCKFILE 
    BLOCK-FILE ?DUP IF FLUSH CLOSE-FILE DROP THEN 
    OFF> BLOCK-FILE ;
  
p4_open_blockfile --- : FCode
OPEN-BLOCKFILE ( "filename" -- ) [FTH] w32for pfe/block-mix.c

w32for-implementation:

    close-blockfile
    parse-word r/w open-file abort" failed to open block-file"
    set-blockfile
    empty-buffers 
  
p4_create_blockfile --- : FCode
CREATE-BLOCKFILE ( blocks-count "filename" -- ) [FTH] w32for pfe/block-mix.c

w32for-implementation:

    close-blockfile
    parse-word r/w create-file abort" failed to create block-file"
    set-blockfile
    dup b/buf m* blockhandle resize-file
    abort" unable to create a file of that size"
    empty-buffers
    0 do i wipe loop 
    flush

pfe does not wipe the buffers

p4_zero_create_blockfile --- : FCode
USING-NEW ( "filename" -- ) [EXT] [obsolete] pfe/block-mix.c

like USING but can create the file OBSOLETE word, use CREATE-BLOCKFILE

  : USING-NEW 0 CREATE-BLOCKFILE ;
  
p4_set_blockfile --- : FCode
SET-BLOCKFILE ( block-file* -- ) [EXT] win32for pfe/block-mix.c

win32forth uses a system-filedescriptor where -1 means unused in the BLOCKHANDLE, but we use a "FILE*"-like structure, so NULL means NOT-IN-USE. Here we set it.

p4_file_access(const p4_char_t *fn, int len) : _export int
 ... pfe/block-sub.c
p4_open_file(const p4_char_t *name, int len, int mode) : _export p4_File *
 ... pfe/block-sub.c
p4_create_file(const p4_char_t *name, int len, int mode) : _export p4_File *
 ... pfe/block-sub.c
p4_close_file(p4_File *fid) : _export int
 ... pfe/block-sub.c
p4_reposition_file(p4_File *fid, _p4_off_t pos) : _export int
 ... pfe/block-sub.c
p4_read_file(void *p, p4ucell *n, p4_File *fid) : _export int
 ... pfe/block-sub.c
p4_write_file(void *p, p4ucell n, p4_File *fid) : _export int
 ... pfe/block-sub.c
p4_resize_file(p4_File *fid, _p4_off_t size) : _export int
 ... pfe/block-sub.c
p4_read_line(void* buf, p4ucell *u, p4_File *fid, p4cell *ior) : _export int
 ... pfe/block-sub.c
p4_read_write(p4_File *fid, void *p, p4ucell n, int readflag) : _export void
 ... pfe/block-sub.c
p4_load_file(const p4_char_t *fn, int cnt, int blk) : _export void
 ... pfe/block-sub.c
p4_sh_else --- : FCode
#ELSE ( -- ) [FTH] pfe/cdecl-ext.c

The implementation of #ELSE is done in C for speed and being less error prone. Better use the ANSI-compatible [IF] [ELSE] [THEN] construct.

p4_sh_endif --- : FCode
#ENDIF ( -- ) [FTH] pfe/cdecl-ext.c

end of #IF #IFDEF #IFNOTDEF and #ELSE contructs

    (a dummy word that does actually nothing, but #ELSE may look for it)
  
p4_sh_if --- : FCode
#IF ( -- C: state-save-flag mfth-if-magic S: ) [FTH] pfe/cdecl-ext.c

prepares for a following #IS_TRUE or #IS_FALSE, does basically switch off compile-mode for the enclosed code.
better use the ANSI style [IF] [ELSE] [THEN] construct.

p4_sh_is_true --- : FCode
#IS_TRUE ( C: state-save-flag mfth-if-magic S: test-flag -- ) [FTH] pfe/cdecl-ext.c

checks the condition on the CS-STACK.
Pairs with #IF
better use the ANSI style [IF] [ELSE] [THEN] construct.

p4_sh_is_false --- : FCode
#IS_FALSE ( C: state-save-flag mfth-if-magic S: test-flag -- ) [FTH] pfe/cdecl-ext.c

checks the condition on the CS-STACK.
Pairs with #IF
better use the ANSI style [IF] [ELSE] [THEN] construct.

p4_sh_ifdef --- : FCode
#IFDEF ( "word" -- ) [FTH] pfe/cdecl-ext.c

better use [DEFINED] word [IF] - the word [IF] is ANSI-conform.

p4_sh_ifnotdef --- : FCode
#IFNOTDEF ( "word" -- ) [FTH] pfe/cdecl-ext.c

better use [DEFINED] word [NOT] [IF] - the word [IF] and [ELSE] are ANSI-conform, while #IFDEF #ELSE are not.

p4_backslash --- : extern FCode
// ( [...] -- ) [FTH] pfe/cdecl-ext.c

a line-comment

p4_sh_define --- : FCode
#define ( "name" "value" -- ) [FTH] pfe/cdecl-ext.c

create an alias, will actually make a DEFERed word, and it has the magic to handle number-arguments

p4_sh_pragma --- : FCode
#pragma ( "word" "evaluate" -- ) [FTH] pfe/cdecl-ext.c

pass the word to ENVIRONMENT? If the word does *not* exist, the rest of the line is parsed away with // - therefore, if the executed word does not consume the line itself, the rest of the line is still executed. examples:

  #pragma warnings on // if warnings is a variable, ON can set it
  #pragma stack-cells 50 < [if] .( not enough stackcells ) [then]
  #pragma simply anything else you like to have in environment or not
 

implementation:

  : #pragma ?exec
    bl word count environment? if exit then ( interpret the rest of the line )
    [compile] \               ( parse away the rest of the line as a comment )
  ;
  
p4_link_comma --- : FCode
link, ( some-list* -- ) [EXT] pfe/chain-ext.c
 
  : link,        here over @ a, swap ! ;
  
p4_new_chain --- : FCode
new-chain ( "name" -- ) [EXT] [DOES: -- new-chain* ] pfe/chain-ext.c

create a new chain and register in chain-link

  : new-chain create: 0 , ['] noop , chain-link link, ;

layout of a chain: /cell field ->chain.link /cell field ->chain.exec /cell field ->chain.next

p4_dot_chain --- : FCode
.chain ( some-chain* -- ) [EXT] pfe/chain-ext.c

show chain - compare with WORDS

p4_dot_chains --- : FCode
.chains ( -- ) [EXT] pfe/chain-ext.c

show all chains registered in the system - compare with VLIST

p4_do_chain --- : FCode
do-chain ( some-chain* -- ) [EXT] pfe/chain-ext.c

execute chain

  : do-chain being @ ?dup while dup>r cell+ @execute r> repeat ;
  
p4_chain_add_before --- : FCode
chain-add-before ( some-chain* "word-to-add" -- ) [EXT] pfe/chain-ext.c

add chain item, for reverse chain like BYE

  : chain-add-before ' >r here over @ , r> , swap ! ;
  ( chain-add-before link, ' , )
  
p4_chain_add --- : FCode
chain-add ( some-chain* "word-to-add" -- ) [EXT] pfe/chain-ext.c

add chain item, for normal setup, at end of do-chain

  : chain-add ' >r begin dup @ while @ repeat here swap ! 0 , r> , ;
  ( chain-add begin dup @ while @ repeat  here swap ! 0, ' , )
  
p4_new_wordlist(p4char* nfa) : _export p4_Wordl*
  create a single-threaded wordlist - compare with p4_make_wordlist pfe/chainlist-ext.c
p4_dot_words --- : FCode
.WORDS ( some-wordlist* -- ) [EXT] pfe/chainlist-ext.c

print the WORDLIST interactivly to the user

  : .WORDS ALSO SET-CONTEXT WORDS PREVIOUS ;

WORDS / ORDER / NEW-WORDLIST / DO-ALL-WORDS

p4_do_all_words --- : FCode
DO-ALL-WORDS ( some-wordlist* -- ) [EXT] pfe/chainlist-ext.c

EXECUTE each entry in the wordlist in the reverse order defined

  : DO-ALL-WORDS
       0 FIRST-NAME
       BEGIN ?DUP WHILE 
          DUP NAME> EXECUTE
          NAME-NEXT
       REPEAT
  ;

to run the NEW-WORDLIST in original order, use REDO-ALL-WORDS

p4_redo_all_words --- : FCode
REDO-ALL-WORDS ( some-wordlist* -- ) [EXT] pfe/chainlist-ext.c

EXECUTE each entry in the wordlist in the original order defined

  : REDO-ALL-WORDS
       0 FIRST-NAME
       0 SWAP ( under )
       BEGIN ?DUP WHILE 
          DUP NAME> SWAP ( under )
          NAME-NEXT
       REPEAT
       BEGIN ?DUP WHILE
          EXECUTE
       REPEAT
  ;

to run the NEW-WORDLIST in last-run-first order, use DO-ALL-WORDS

p4_do_all_words_while_loop --- : FCode
DO-ALL-WORDS-WHILE-LOOP ( some-wordlist* test-xt* -- ) [EXT] pfe/chainlist-ext.c

EXECUTE each entry in the wordlist in the reverse order defined but only as long as after EXECUTE of "word" a TRUE flag is left on the stack. The wordlist execution is cut when a FALSE flag is seen. (the current wordlist entry is _not_ on the stack!)

  : DO-ALL-WORDS-WHILE-LOOP >R
       0 FIRST-NAME
       BEGIN ?DUP WHILE 
          R@ EXECUTE 0= IF R>DROP DROP EXIT THEN
          DUP NAME> EXECUTE
          NAME-NEXT
       REPEAT R>DROP
  ;

compare with DO-ALL-WORDS-WHILE

p4_do_all_words_while --- : FCode
DO-ALL-WORDS-WHILE ( some-wordlist* "word" -- ) [EXT] pfe/chainlist-ext.c

EXECUTE each entry in the wordlist in the reverse order defined but only as long as after EXECUTE of "word" a TRUE flag is left on the stack. The wordlist execution is cut when a FALSE flag is seen. (the current wordlist entry is _not_ on the stack!)

  : DO-ALL-WORDS-WHILE ' 
       STATE @ IF LITERAL, COMPILE DO-ALL-WORDS-WHILE-LOOP EXIT THEN
       >R 0 FIRST-NAME
       BEGIN ?DUP WHILE 
          R@ EXECUTE 0= IF R>DROP DROP EXIT THEN
          DUP NAME> EXECUTE
          NAME-NEXT
       REPEAT R>DROP
  ;

to run the NEW-WORDLIST in original order, use REDO-ALL-WORDS

p4_do_synonym --- : FCode
DO-SYNONYM ( some-wordlist* "do-name" "orig-name" -- ) [EXT] pfe/chainlist-ext.c

create a SYNONYM in the specified wordlist.

  : DO-SYNONYM GET-CURRENT SWAP SET-CURRENT SYNONYM SET-CURRENT ;

DO-ALIAS / DO-ALL-WORDS / NEW-WORDLIST / WORDLIST / ORDER

p4_alias_atexit --- : FCode
ALIAS-ATEXIT ( some-xt* "name" -- ) [EXT] pfe/chainlist-ext.c

create a defer word that is initialized with the given x-token.

  : ALIAS-ATEXIT ATEXIT-WORDLIST DO-ALIAS ;

ATEXIT-WORDLIST DO-ALL-WORDS

p4_do_alias --- : FCode
DO-ALIAS ( some-xt* definition-wordlist* "do-name" -- ) [EXT] pfe/chainlist-ext.c

create an ALIAS with the exec-token in the specified wordlist

  : DO-ALIAS GET-CURRENT SWAP SET-CURRENT SWAP ALIAS SET-CURRENT ;

DO-SYNONYM

p4_z_fetch --- : FCode
Z@ ( addr -- f: z ) pfe/complex-ext.c
p4_z_store --- : FCode
Z! ( addr f: z -- ) pfe/complex-ext.c
p4_x_fetch --- : FCode
X@ ( zaddr -- f: x ) pfe/complex-ext.c
p4_x_store --- : FCode
X! ( zaddr f: x -- ) pfe/complex-ext.c
p4_y_fetch --- : FCode
Y@ ( zaddr -- f: y ) pfe/complex-ext.c
p4_y_store --- : FCode
Y! ( zaddr f: x -- ) pfe/complex-ext.c
p4_z_dot --- : FCode
Z. (f: z -- ) pfe/complex-ext.c

Emit the complex number, including the sign of zero when signbit() is available.

p4_z_s_dot --- : FCode
ZS. (f: z -- ) pfe/complex-ext.c

Emit the complex number in scientific notation, including the sign of zero when signbit() is available.

p4_real --- : FCode
REAL (f: x y -- x ) pfe/complex-ext.c
p4_imag --- : FCode
IMAG (f: x y -- y ) pfe/complex-ext.c
p4_conjg --- : FCode
CONJG (f: x y -- x -y ) pfe/complex-ext.c
p4_z_drop --- : FCode
ZDROP (f: z -- ) pfe/complex-ext.c
p4_z_dup --- : FCode
ZDUP (f: z -- z z ) pfe/complex-ext.c
p4_z_swap --- : FCode
ZSWAP (f: z1 z2 -- z2 z1 ) pfe/complex-ext.c
p4_z_over --- : FCode
ZOVER (f: z1 z2 -- z1 z2 z1 ) pfe/complex-ext.c
p4_z_nip --- : FCode
ZNIP (f: z1 z2 -- z2 ) pfe/complex-ext.c
p4_z_tuck --- : FCode
ZTUCK (f: z1 z2 -- z2 z1 z2 ) pfe/complex-ext.c
p4_z_rot --- : FCode
ZROT (f: z1 z2 z3 -- z2 z3 z1 ) pfe/complex-ext.c
p4_minus_z_rot --- : FCode
-ZROT (f: z1 z2 z3 -- z3 z1 z2 ) pfe/complex-ext.c
p4_z_plus --- : FCode
Z+ (f: z1 z2 -- z1+z2 ) pfe/complex-ext.c
p4_z_minus --- : FCode
Z- (f: z1 z2 -- z1-z2 ) pfe/complex-ext.c
p4_z_star --- : FCode
Z* (f: x y u v -- x*u-y*v x*v+y*u ) pfe/complex-ext.c

Uses the algorithm followed by JVN: (x+iy)*(u+iv) = [(x+y)*u - y*(u+v)] + i[(x+y)*u + x*(v-u)] Requires 3 multiplications and 5 additions.

p4_z_slash --- : FCode
Z/ (f: u+iv z -- u/z+iv/z ) pfe/complex-ext.c

Kahan-like algorithm *without* due attention to spurious over/underflows and zeros and infinities.

p4_z_negate --- : FCode
ZNEGATE (f: z -- -z ) pfe/complex-ext.c
p4_z_two_star --- : FCode
Z2* (f: z -- z*2 ) pfe/complex-ext.c
p4_z_two_slash --- : FCode
Z2/ (f: z -- z/2 ) pfe/complex-ext.c
p4_i_star --- : FCode
I* (f: x y -- -y x ) pfe/complex-ext.c
p4_minus_i_star --- : FCode
-I* (f: x y -- y -x ) pfe/complex-ext.c
p4_one_slash_z --- : FCode
1/Z (f: z -- 1/z ) pfe/complex-ext.c

Kahan algorithm *without* due attention to spurious over/underflows and zeros and infinities.

p4_z_hat_two --- : FCode
Z^2 (f: z -- z^2 ) pfe/complex-ext.c

Kahan algorithm without removal of any spurious NaN created by overflow. It deliberately uses (x-y)(x+y) instead of x^2-y^2 for the real part.

p4_z_abs_hat_two --- : FCode
|Z|^2 (f: x y -- |z|^2 ) pfe/complex-ext.c
p4_z_hat_n --- : FCode
Z^N ( n f: z -- z^n ) pfe/complex-ext.c
p4_x_plus --- : FCode
X+ (f: z a -- x+a y ) pfe/complex-ext.c
p4_x_minus --- : FCode
X- (f: z a -- x-a y ) pfe/complex-ext.c
p4_y_plus --- : FCode
Y+ (f: z a -- x y+a ) pfe/complex-ext.c
p4_y_minus --- : FCode
Y- (f: z a -- x y-a ) pfe/complex-ext.c
p4_z_star_f --- : FCode
Z*F (f: x y f -- x*f y*f ) pfe/complex-ext.c
p4_z_slash_f --- : FCode
Z/F (f: x y f -- x/f y/f ) pfe/complex-ext.c
p4_f_star_z --- : FCode
F*Z (f: f x y -- f*x f*y ) pfe/complex-ext.c
p4_f_slash_z --- : FCode
F/Z (f: f z -- f/z ) pfe/complex-ext.c

Kahan algorithm *without* due attention to spurious over/underflows and zeros and infinities.

p4_z_star_i_star_f --- : FCode
Z*I*F (f: z f -- z*if ) pfe/complex-ext.c
p4_minus_i_star_z_slash_f --- : FCode
-I*Z/F (f: z f -- z/[if] ) pfe/complex-ext.c
p4_i_star_f_star_z --- : FCode
I*F*Z (f: f z -- if*z ) pfe/complex-ext.c
p4_i_star_f_slash_z --- : FCode
I*F/Z (f: f z -- [0+if]/z ) pfe/complex-ext.c

Kahan algorithm *without* due attention to spurious over/underflows and zeros and infinities.

p4_z_star_to_real --- : FCode
Z*>REAL (f: z1 z2 -- Re[z1*z2] ) pfe/complex-ext.c

Compute the real part of the complex product without computing the imaginary part. Recommended by Kahan to avoid gratuitous overflow or underflow signals from the unnecessary part.

p4_z_star_to_imag --- : FCode
Z*>IMAG (f: z1 z2 -- Im[z1*z2] ) pfe/complex-ext.c

Compute the imaginary part of the complex product without computing the real part.

p4_z_abs --- : FCode
|Z| (f: x y -- |z| ) pfe/complex-ext.c
p4_z_box --- : FCode
ZBOX (f: z -- box[z] ) pfe/complex-ext.c

Defined *only* for zero and infinite arguments. This difffers from Kahan's CBOX [p. 198] by conserving signs when only one of x or y is infinite, consistent with the other cases, and with its use in his ARG [p. 199].

p4_arg --- : FCode
ARG (f: z -- principal.arg[z] ) pfe/complex-ext.c
p4_to_polar --- : FCode
>POLAR (f: x y -- r theta ) pfe/complex-ext.c

Convert the complex number z to its polar representation, where theta is the principal argument.

p4_polar_from --- : FCode
POLAR> (f: r theta -- x y ) pfe/complex-ext.c
p4_z_ssqs --- : FCode
ZSSQS (f: z -- rho s: k ) pfe/complex-ext.c

Compute rho = |(x+iy)/2^k|^2, scaled to avoid overflow or underflow, and leave the scaling integer k. Kahan, p. 200.

p4_z_sqrt --- : FCode
ZSQRT (f: z -- sqrt[z] ) pfe/complex-ext.c

Compute the principal branch of the square root, with Re sqrt[z] >= 0. Kahan, p. 201.

p4_z_ln --- : FCode
ZLN (f: z -- ln|z|+i*theta ) pfe/complex-ext.c

Compute the principal branch of the complex natural logarithm. The angle theta is the principal argument. This code uses Kahan's algorithm for the scaled logarithm CLOGS(z,J) = ln(z*2^J), with J=0 and blind choices of the threshholds T0, T1, and T2. Namely, T0 = 1/sqrt(2), T1 = 5/4, and T2 = 3;

p4_z_exp --- : FCode
ZEXP (f: z -- exp[z] ) pfe/complex-ext.c
p4_z_hat --- : FCode
Z^ (f: x y u v -- [x+iy]^[u+iv] ) pfe/complex-ext.c

Compute in terms of the principal argument of x+iy.

p4_z_cosh --- : FCode
ZCOSH (f: z -- cosh[z] ) pfe/complex-ext.c
p4_z_sinh --- : FCode
ZSINH (f: z -- sinh[z] ) pfe/complex-ext.c
p4_z_tanh --- : FCode
ZTANH (f: z -- tanh[z] ) pfe/complex-ext.c

Kahan, p. 204, including his divide by zero signal suppression for infinite values of tan(). To quote the very informative "=>'man math'" on our Darwin system about IEEE 754: "Divide-by-Zero is signaled only when a function takes exactly infinite values at finite operands."

p4_z_coth --- : FCode
ZCOTH (f: z -- 1/tanh[z] ) pfe/complex-ext.c
p4_z_cos --- : FCode
ZCOS (f: z -- cosh[i*z] ) pfe/complex-ext.c
p4_z_sin --- : FCode
ZSIN (f: z -- -i*sinh[i*z] ) pfe/complex-ext.c
p4_z_tan --- : FCode
ZTAN (f: z -- -i*tanh[i*z] ) pfe/complex-ext.c
p4_z_cot --- : FCode
ZCOT (f: z -- -i*coth[-i*z] ) pfe/complex-ext.c
p4_z_acos --- : FCode
ZACOS (f: z -- u+iv=acos[z] ) pfe/complex-ext.c

Kahan, p.202.

p4_z_acosh --- : FCode
ZACOSH (f: z -- u+iv=acosh[z] ) pfe/complex-ext.c

Kahan, p.203.

p4_z_asin --- : FCode
ZASIN (f: z -- u+iv=asin[z] ) pfe/complex-ext.c

Kahan, p.203.

p4_z_asinh --- : FCode
ZASINH (f: z -- -i*asin[i*z] ) pfe/complex-ext.c

Kahan, p. 203, couth.

p4_z_atanh --- : FCode
ZATANH (f: z -- u+iv=atanh[z] ) pfe/complex-ext.c

Kahan, p. 203.

p4_z_atan --- : FCode
ZATAN (f: z -- -i*atanh[i*z] ) pfe/complex-ext.c

Kahan, p. 204, couth.

p4_z_constant --- : FCode
ZCONSTANT ( "name" f: z -- ) "name" execution: (f: -- z ) pfe/complex-ext.c

Define a word that leaves x+iy on the fp stack upon execution.

p4_z_literal --- : FCode
ZLITERAL Compilation: (f: z -- ) Run: (f: -- z ) pfe/complex-ext.c
p4_z_variable --- : FCode
ZVARIABLE ( "name" -- ) "name" exection: ( -- zaddr ) pfe/complex-ext.c

Allocate aligned memory for an fp complex number, with the real part first in memory, and define a word that leaves the address on the data stack.

p4_store --- : FCode
! ( value some-cell* -- | value addr* -- [?] ) [ANS] pfe/core-ext.c

store value at addr (sizeof CELL)

p4_sh --- : FCode
# ( n,n -- n,n' ) [ANS] pfe/core-ext.c

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word divides the argument by BASE and add it to the picture space - it should be used inside of <# and #>

p4_sh_greater --- : FCode
#> ( n,n -- hold-str-ptr hold-str-len ) [ANS] pfe/core-ext.c

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word drops the argument and returns the picture space buffer

p4_sh_s --- : FCode
#S ( n,n -- 0,0 ) [ANS] pfe/core-ext.c

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word does repeat the word # for a number of times, until the argument becomes zero. Hence the result is always null - it should be used inside of <# and #>

p4_tick --- : FCode
"'" ( 'name' -- name-xt* ) [ANS] pfe/core-ext.c

return the execution token of the following name. This word is _not_ immediate and may not do what you expect in compile-mode. See ['] and '> - note that in FIG-forth the word of the same name had returned the PFA (not the CFA) and was immediate/smart, so beware when porting forth-code from FIG-forth to ANSI-forth.

p4_paren --- : FCode
"(" ( 'comment' -- ) [ANS] pfe/core-ext.c

eat everything up to the next closing paren - treat it as a comment.

p4_star --- : FCode
"*" ( a# b# -- mul-a#' | a b -- mul-a' [??] ) [ANS] pfe/core-ext.c

return the multiply of the two args

p4_star_slash --- : FCode
"*\/" ( a# b# c# -- scale-a#' | a b c -- scale-a' [??] ) [ANS] pfe/core-ext.c

regard the b/c as element Q - this word has an advantage over the sequence of * and / by using an intermediate double-cell value

p4_star_slash_mod --- : FCode
"*\/MOD" ( a# b# c# -- div-a# mod-a# | a b c -- div-a mod-a [??] ) [ANS] pfe/core-ext.c

has an adavantage over the sequence of * and /MOD by using an intermediate double-cell value.

p4_plus --- : FCode
+ ( a* b# -- a*' | a# b* -- b*' | a# b# -- a#' | a b -- a' [??] ) [ANS] pfe/core-ext.c

return the sum of the two args

p4_plus_store --- : FCode
+! ( value# some-cell* -- | value some* -- [?] ) [ANS] pfe/core-ext.c

add val to the value found in addr

  simulate:
    : +! TUCK @ + SWAP ! ;
  
p4_plus_loop_execution --- : FCode_XE
"((+LOOP))" ( increment# -- ) [HIDDEN] pfe/core-ext.c

compiled by +LOOP

p4_plus_loop --- : FCode
+LOOP ( increment# R: some,loop -- ) [ANS] pfe/core-ext.c

compile ((+LOOP)) which will use the increment as the loop-offset instead of just 1. See the DO and LOOP construct.

p4_comma --- : FCode
"," ( value* -- | value# -- | value -- [?] ) [ANS] pfe/core-ext.c

store the value in the dictionary

  simulate:
    : , DP  1 CELLS DP +!  ! ;
  
p4_minus --- : FCode
"-" ( a* b# -- a*' | a# b* -- b*' | a# b# -- a#' | a* b* -- diff-b#' | a b -- a' [??] ) [ANS] pfe/core-ext.c

return the difference of the two arguments

p4_dot --- : FCode
"." ( value# -- | value* -- [?] | value -- [??] ) [ANS] pfe/core-ext.c

print the numerical value to stdout - uses BASE

p4_dot_quote_execution --- : FCode_XE
'((.\"))' ( -- ) [HIDDEN] skipstring pfe/core-ext.c

compiled by => ." string"

p4_dot_quote --- : FCode
'.\"' ( [string<">] -- ) [ANS] pfe/core-ext.c

print the string to stdout

p4_slash --- : FCode
"/" ( a# b# -- a#' | a b -- a' [???] ) [ANS] pfe/core-ext.c

return the quotient of the two arguments

p4_slash_mod --- : FCode
"/MOD" ( a# b# -- div-a#' mod-a#' | a b -- div-a' mod-a' [??] ) [ANS] pfe/core-ext.c

divide a and b and return both quotient n and remainder m

p4_zero_less --- : FCode
0< ( value -- test-flag ) [ANS] pfe/core-ext.c

return a flag that is true if val is lower than zero

  simulate:
   : 0< 0 < ;
  
p4_zero_equal --- : FCode
0= ( 0 -- test-flag! | value! -- 0 | value -- test-flag ) [ANS] pfe/core-ext.c

return a flag that is true if val is just zero

  simulate:
   : 0= 0 = ;
  
p4_one_plus --- : FCode
1+ ( value -- value' ) [ANS] pfe/core-ext.c

return the value incremented by one

  simulate:
   : 1+ 1 + ;
  
p4_one_minus --- : FCode
1- ( value -- value' ) [ANS] pfe/core-ext.c

return the value decremented by one

  simulate:
    : 1- 1 - ;
  
p4_two_store --- : FCode
2! ( x,x variable* -- ) [ANS] pfe/core-ext.c

double-cell store

p4_two_star --- : FCode
2* ( a# -- a#' | a -- a' [??] ) [ANS] pfe/core-ext.c

multiplies the value with two - but it does actually use a shift1 to be faster

  simulate:
   : 2* 2 * ; ( canonic) : 2* 1 LSHIFT ; ( usual)
  
p4_two_slash --- : FCode
2/ ( a# -- a#' | a -- a' [??] ) [ANS] pfe/core-ext.c

divides the value by two - but it does actually use a shift1 to be faster

  simulate:
   : 2/ 2 / ; ( canonic) : 2/ 1 RSHIFT ; ( usual)
  
p4_two_fetch --- : FCode
2@ ( variable* -- x,x ) [ANS] pfe/core-ext.c

double-cell fetch

p4_two_drop --- : FCode
2DROP ( a b -- ) [ANS] pfe/core-ext.c

double-cell drop, also used to drop two items

p4_two_dup --- : FCode
2DUP ( a,a -- a,a a,a ) [ANS] pfe/core-ext.c

double-cell duplication, also used to duplicate two items

  simulate:
    : 2DUP OVER OVER ; ( wrong would be : 2DUP DUP DUP ; !!)
  
p4_two_over --- : FCode
2OVER ( a,a b,b -- a,a b,b a,a ) [ANS] pfe/core-ext.c

double-cell over, see OVER and 2DUP

  simulate:
    : 2OVER SP@ 2 CELLS + 2@ ;
  
p4_two_swap --- : FCode
2SWAP ( a,a b,b -- b,b a,a ) [ANS] pfe/core-ext.c

double-cell swap, see SWAP and 2DUP

  simulate:
    : 2SWAP LOCALS| B1 B2 A1 A2 | B2 B1 A2 A1 ;
  
p4_colon_RT --- : FCode_RT
"(NEST)" ( -- ) [HIDDEN] pfe/core-ext.c

compiled by : (see also (NONAME) compiled by :NONAME )

p4_colon --- : FCode
":" ( 'name' -- ) [ANS] [NEW] pfe/core-ext.c

create a header for a nesting word and go to compiling mode then. This word is usually ended with ; but the execution of the resulting colon-word can also return with EXIT

p4_semicolon_execution --- : FCode_XE
"((;))" ( -- ) [HIDDEN] [EXIT] pfe/core-ext.c

compiled by ; and maybe ;AND -- it will perform an EXIT

p4_semicolon --- : FCode
";" ( -- ) [ANS] [EXIT] [END] pfe/core-ext.c

compiles ((;)) which does EXIT the current colon-definition. It does then end compile-mode and returns to execute-mode. See : and :NONAME

p4_less_than --- : FCode
< ( a* b* -- test-flag | a# b# -- test-flag | a b -- test-flag [?] ) [ANS] pfe/core-ext.c

return a flag telling if a is lower than b

p4_less_sh --- : FCode
<# ( -- ) [ANS] pfe/core-ext.c

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word does initialize the pictured numeric output space.

p4_equals --- : FCode
= ( a* b* -- test-flag | a# b# -- test-flag | a b -- test-flag [?] ) [ANS] pfe/core-ext.c

return a flag telling if a is equal to b

p4_greater_than --- : FCode
> ( a* b* -- test-flag | a# b# -- test-flag | a b -- test-flag [?] ) [ANS] pfe/core-ext.c

return a flag telling if a is greater than b

p4_to_body --- : FCode
>BODY ( some-xt* -- some-body* ) [ANS] pfe/core-ext.c

adjust the execution-token (ie. the CFA) to point to the parameter field (ie. the PFA) of a word. this is not a constant operation - most words have their parameters at "1 CELLS +" but CREATE/DOES-words have the parameters at "2 CELLS +" and ROM/USER words go indirect with a rom'ed offset i.e. "CELL + @ UP +"

p4_to_number --- : FCode
>NUMBER ( a,a str-ptr str-len -- a,a' str-ptr' str-len) [ANS] pfe/core-ext.c

try to convert a string into a number, and place that number at a,a respeciting BASE

p4_to_r --- : FCode
>R ( value -- R: value ) [ANS] pfe/core-ext.c

save the value onto the return stack. The return stack must be returned back to clean state before an exit and you should note that the return-stack is also touched by the DO ... WHILE loop. Use R> to clean the stack and R@ to get the last value put by >R

p4_Q_dup --- : FCode
?DUP ( 0 -- 0 | value! -- value! value! | value -- 0 | value! value! ) [ANS] pfe/core-ext.c

one of the rare words whose stack-change is condition-dependet. This word will duplicate the value only if it is not zero. The usual place to use it is directly before a control-word that can go to different places where we can spare an extra DROP on the is-null-part. This makes the code faster and often a little easier to read.

  example:
    : XX BEGIN ?DUP WHILE DUP . 2/ REPEAT ; instead of
    : XX BEGIN DUP WHILE DUP . 2/ REPEAT DROP ;
  
p4_fetch --- : FCode
@ ( value* -- value ) [ANS] pfe/core-ext.c

fetch the value from the variables address

p4_abs --- : FCode
ABS ( value# -- value#' ) [ANS] pfe/core-ext.c

return the absolute value

p4_accept --- : FCode
ACCEPT ( buffer-ptr buffer-max -- buffer-len ) [ANS] pfe/core-ext.c

get a string from terminal into the named input buffer, returns the number of bytes being stored in the buffer. May provide line-editing functions.

p4_align --- : FCode
ALIGN ( -- ) [ANS] pfe/core-ext.c

will make the dictionary aligned, usually to a cell-boundary, see ALIGNED

p4_aligned --- : FCode
ALIGNED ( addr -- addr' ) [ANS] pfe/core-ext.c

uses the value (being usually a dictionary-address) and increment it to the required alignment for the dictionary which is usually in CELLS - see also ALIGN

p4_allot --- : FCode
ALLOT ( allot-count -- ) [ANS] pfe/core-ext.c

make room in the dictionary - usually called after a CREATE word like VARIABLE or VALUE to make for an array of variables. Does not initialize the space allocated from the dictionary-heap. The count is in bytes - use CELLS ALLOT to allocate a field of cells.

p4_and --- : FCode
AND ( value mask -- value' ) [ANS] pfe/core-ext.c

mask with a bitwise and - be careful when applying it to logical values.

p4_begin --- : FCode
BEGIN ( -- ) [ANS] [LOOP] pfe/core-ext.c

start a control-loop, see WHILE and REPEAT

p4_c_store --- : FCode
C! ( value# variable#* -- | value# variable* [?] ) [ANS] pfe/core-ext.c

store the byte-value at address, see => !

p4_c_comma --- : FCode
C, ( value# -- ) [ANS] pfe/core-ext.c

store a new byte-value in the dictionary, implicit 1 ALLOT, see => ,

p4_c_fetch --- : FCode
C@ ( value#* -- value# | value* -- value# [?] ) [ANS] pfe/core-ext.c

fetch a byte-value from the address, see @

p4_cell_plus --- : FCode
CELL+ ( value -- value' ) [ANS] pfe/core-ext.c

adjust the value by adding a single Cell's width - the value is often an address or offset, see CELLS

p4_cells --- : FCode
CELLS ( value# -- value#' ) [ANS] pfe/core-ext.c

scale the value by the sizeof a Cell the value is then often applied to an address or fed into ALLOT

p4_char --- : FCode
CHAR ( 'word' -- char# ) [ANS] pfe/core-ext.c

return the (ascii-)value of the following word's first character.

p4_char_plus --- : FCode
CHAR+ ( value -- value' ) [ANS] pfe/core-ext.c

increment the value by the sizeof one char - the value is often a pointer or an offset, see CHARS

p4_chars --- : FCode
CHARS ( value# -- value#' ) [ANS] pfe/core-ext.c

scale the value by the sizeof a char - the value is then often applied to an address or fed into ALLOT (did you expect that sizeof(p4char) may actually yield 2 bytes?)

p4_constant_RT --- : FCode_RT
"((CONSTANT))" ( -- ) [HIDDEN] pfe/core-ext.c

runtime compiled by CONSTANT

p4_constant --- : FCode
CONSTANT ( value 'name' -- ) [ANS] [DOES: -- value ] pfe/core-ext.c

CREATE a new word with runtime ((CONSTANT)) so that the value placed here is returned everytime the constant's name is used in code. See VALUE for constant-like names that are expected to change during execution of the program. In a ROM-able forth the CONSTANT-value may get into a shared ROM-area and is never copied to a RAM-address.

p4_count --- : FCode
COUNT ( string-bstr* -- string-ptr' string-len | some* -- some*' some-len [?] ) [ANS] pfe/core-ext.c

usually before calling TYPE

(as an unwarranted extension, this word does try to be idempotent).

p4_cr --- : FCode
CR ( -- ) [ANS] pfe/core-ext.c

print a carriage-return/new-line on stdout

p4_decimal --- : FCode
DECIMAL ( -- ) [ANS] pfe/core-ext.c

set the BASE to 10

  simulate:
    : DECIMAL 10 BASE ! ;
  
p4_depth --- : FCode
DEPTH ( -- depth# ) [ANS] pfe/core-ext.c

return the depth of the parameter stack before the call, see SP@ - the return-value is in CELLS

p4_do_execution --- : FCode_XE
"((DO))" ( end# start# -- ) [HIDDEN] pfe/core-ext.c

compiled by DO

p4_do --- : FCode
DO ( end# start# | end* start* -- R: some,loop ) [ANS] [LOOP] pfe/core-ext.c

pushes $end and $start onto the return-stack ( >R ) and starts a control-loop that ends with LOOP or +LOOP and may get a break-out with LEAVE . The loop-variable can be accessed with I

p4_variable_RT --- : FCode_RT
"((VAR))" ( -- pfa ) [HIDDEN] pfe/core-ext.c

the runtime compiled by VARIABLE

p4_builds_RT --- : FCode
"((BUILDS))" ( -- pfa ) [HIDDEN] pfe/core-ext.c

the runtime compiled by CREATE which is not much unlike a VARIABLE (in ANS Forth Mode we reserve an additional DOES-field)

p4_does_RT --- : FCode_RT
"((DOES>))" ( -- pfa ) [HIDDEN] pfe/core-ext.c

runtime compiled by DOES>

p4_does_execution --- : FCode_XE
"(DOES>)" ( -- pfa ) [HIDDEN] pfe/core-ext.c

execution compiled by DOES>

p4_does --- : FCode
"DOES>" ( -- does* ) [ANS] [END] [NEW] pfe/core-ext.c

does twist the last CREATE word to carry the (DOES>) runtime. That way, using the word will execute the code-piece following DOES> where the pfa of the word is already on stack. (note: FIG option will leave pfa+cell since does-rt is stored in pfa)

p4_builds --- : FCode
pfe/core-ext.c

make a HEADER whose runtime will be changed later using DOES>
note that ans'forth does not define and it suggests to use CREATE directly.
... if you want to write FIG-programs in pure pfe then you have to use CREATE: to get the FIG-like meaning of CREATE whereas the ans-forth CREATE is the same as

  : <BUILDS BL WORD HEADER DOCREATE A, 0 A, ;
  
p4_drop --- : FCode
DROP ( a -- ) [ANS] pfe/core-ext.c

just drop the word on the top of stack, see DUP

p4_dup --- : FCode
DUP ( a -- a a ) [ANS] pfe/core-ext.c

duplicate the cell on top of the stack - so the two topmost cells have the same value (they are equal w.r.t = ) , see DROP for the inverse

p4_branch_execution --- : FCode_XE
"(BRANCH)" ( -- ) [HIDDEN] pfe/core-ext.c

execution compiled by ELSE - just a simple BRANCH

p4_else_execution --- : FCode_XE
"((ELSE))" ( -- ) OBSOLETE (FIXME: to be removed in pfe-34) pfe/core-ext.c
p4_else --- : FCode
ELSE ( -- ) [HIDDEN] pfe/core-ext.c

will compile an ((ELSE)) BRANCH that performs an unconditional jump to the next THEN - and it resolves an IF for the non-true case

p4_emit --- : FCode
EMIT ( char# -- ) [ANS] pfe/core-ext.c

print the char-value on stack to stdout

p4_environment_Q_core --- : FCode
ENVIRONMENT? ( name-ptr name-len -- 0 | ?? name-flag! ) [ANS] pfe/core-ext.c

check the environment for a property, usually a condition like questioning the existance of specified wordset, but it can also return some implementation properties like "WORDLISTS" (the length of the search-order) or "#LOCALS" (the maximum number of locals)

Here it implements the environment queries as a SEARCH-WORDLIST in a user-visible vocabulary called ENVIRONMENT

  : ENVIRONMENT?
    ['] ENVIRONMENT >WORDLIST SEARCH-WORDLIST
    IF  EXECUTE TRUE ELSE  FALSE THEN ;
  
p4_evaluate --- : FCode
EVALUATE ( str-ptr str-len -- ) [ANS] pfe/core-ext.c

INTERPRET the given string, SOURCE id is -1 during that time.

p4_execute --- : FCode
EXECUTE ( some-xt* -- ??? ) [ANS] pfe/core-ext.c

run the execution-token on stack - this will usually trap if it was null for some reason, see >EXECUTE

  simulate:
   : EXECUTE >R EXIT ;
  
p4_exit --- : FCode
EXIT ( -- ) [ANS] [EXIT] pfe/core-ext.c

will unnest the current colon-word so it will actually return the word calling it. This can be found in the middle of a colon-sequence between : and ;

p4_fill --- : FCode
FILL ( mem-ptr mem-len char# -- ) [ANS] pfe/core-ext.c

fill a memory area with the given char, does now simply call p4_memset()

p4_find --- : FCode
FIND ( name-bstr* -- name-bstr* 0 | name-xt* -1|1 ) [ANS] pfe/core-ext.c

looks into the current search-order and tries to find the name string as the name of a word. Returns its execution-token or the original-bstring if not found, along with a flag-like value that is zero if nothing could be found. Otherwise it will be 1 (a positive value) if the word had been immediate, -1 otherwise (a negative value).

p4_f_m_slash_mod --- : FCode
"FM/MOD" ( n1,n1# n2# -- div-n1# mod-n1# ) [ANS] pfe/core-ext.c

divide the double-cell value n1 by n2 and return both (floored) quotient n and remainder m

p4_here --- : FCode
HERE ( -- here* ) [ANS] pfe/core-ext.c

used with WORD and many compiling words

  simulate:   : HERE DP @ ;
  
p4_hold --- : FCode
HOLD ( char# -- ) [ANS] pfe/core-ext.c

the old-style forth-formatting system -- this word adds a char to the picutred output string.

p4_i --- : FCode
I ( R: some,loop -- S: i# ) [ANS] pfe/core-ext.c

returns the index-value of the innermost DO .. LOOP

p4_q_branch_execution --- : FCode_XE
"(?BRANCH)" ( -- ) [HIDDEN] pfe/core-ext.c

execution word compiled by IF - just some simple => ?BRANCH

p4_if_execution --- : FCode_XE
"((IF))" ( -- ) OBSOLETE (FIXME: to be removed in pfe-34) pfe/core-ext.c

use (?BRANCH)

p4_if --- : FCode
IF ( value -- ) [ANS] pfe/core-ext.c

checks the value on the stack (at run-time, not compile-time) and if true executes the code-piece between IF and the next ELSE or THEN . Otherwise it has compiled a branch over to be executed if the value on stack had been null at run-time.

p4_immediate --- : FCode
IMMEDIATE ( -- ) [ANS] pfe/core-ext.c

make the LATEST word immediate, see also CREATE

p4_invert --- : FCode
INVERT ( value# -- value#' ) [ANS] pfe/core-ext.c

make a bitwise negation of the value on stack. see also NEGATE

p4_j --- : FCode
J ( R: some,loop -- S: j# ) [ANS] pfe/core-ext.c

get the current DO ... LOOP index-value being the not-innnermost. (the second-innermost...) see also for the other loop-index-values at I and K

p4_key --- : FCode
KEY ( -- char# ) [ANS] pfe/core-ext.c

return a single character from the keyboard - the key is not echoed.

p4_leave --- : FCode
LEAVE ( R: some,loop -- R: some,loop ) [ANS] pfe/core-ext.c

quit the innermost DO .. LOOP - it does even clean the return-stack and branches to the place directly after the next LOOP

p4_literal_execution --- : FCode_XE
"((LIT))" ( -- value ) [HIDDEN] pfe/core-ext.c

execution compiled by LITERAL

p4_literal --- : FCode
LITERAL ( C: value -- S: value ) [ANS] pfe/core-ext.c

if compiling this will take the value from the compiling-stack and puts in dictionary so that it will pop up again at the run-time of the word currently in creation. This word is used in compiling words but may also be useful in making a hard-constant value in some code-piece like this:

  : DCELLS [ 2 CELLS ] LITERAL * ; ( will save a multiplication at runtime)

(in most configurations this word is statesmart and it will do nothing in interpret-mode. See LITERAL, for a non-immediate variant)

p4_loop_execution --- : FCode_XE
"((LOOP))" ( -- ) [HIDDEN] pfe/core-ext.c

execution compiled by LOOP

p4_loop --- : FCode
LOOP ( R: some,loop -- ) [ANS] [REPEAT] pfe/core-ext.c

resolves a previous DO thereby compiling ((LOOP)) which does increment/decrement the index-value and branch back if the end-value of the loop has not been reached.

p4_l_shift --- : FCode
LSHIFT ( value# shift-count -- value#' ) [ANS] pfe/core-ext.c

does a bitwise left-shift on value

p4_m_star --- : FCode
M* ( a# b# -- a,a#' ) [ANS] pfe/core-ext.c

multiply and return a double-cell result

p4_max --- : FCode
MAX ( a# b# -- a#|b# | a* b* -- a*|b* | a b -- a|b [??] ) [ANS] pfe/core-ext.c

return the maximum of a and b

p4_min --- : FCode
MIN ( a# b# -- a#|b# | a* b* -- a*|b* | a b -- a|b [??] ) [ANS] pfe/core-ext.c

return the minimum of a and b

p4_mod --- : FCode
MOD ( a# b# -- mod-a# | a b# -- mod-a# [??] ) [ANS] pfe/core-ext.c

return the module of "a mod b"

p4_move --- : FCode
MOVE ( from-ptr to-ptr move-len -- ) [ANS] pfe/core-ext.c

p4_memcpy an area

p4_negate --- : FCode
NEGATE ( value# -- value#' ) [ANS] pfe/core-ext.c

return the arithmetic negative of the (signed) cell

  simulate:   : NEGATE -1 * ;
  
p4_or --- : FCode
OR ( a b# -- a' | a# b -- b' | a b -- a' [??] ) [ANS] pfe/core-ext.c

return the bitwise OR of a and b - unlike AND this is usually safe to use on logical values

p4_over --- : FCode
OVER ( a b -- a b a ) [ANS] pfe/core-ext.c

get the value from under the top of stack. The inverse operation would be TUCK

p4_postpone_execution --- : FCode_XE
"((POSTPONE))" ( -- ) [HIDDEN] pfe/core-ext.c

execution compiled by POSTPONE

p4_postpone --- : FCode
POSTPONE ( [word] -- ) [ANS] pfe/core-ext.c

will compile the following word at the run-time of the current-word which is a compiling-word. The point is that POSTPONE takes care of the fact that word may be an IMMEDIATE-word that flags for a compiling word, so it must be executed (and not pushed directly) to compile sth. later. Choose this word in favour of COMPILE (for non-immediate words) and [COMPILE] (for immediate words)

p4_quit --- : FCode
QUIT ( -- ) [EXIT] pfe/core-ext.c

this will throw and lead back to the outer-interpreter. traditionally, the outer-interpreter is called QUIT in forth itself where the first part of the QUIT-word had been to clean the stacks (and some other variables) and then turn to an endless loop containing QUERY and EVALUATE (otherwise known as INTERPRET ) - in pfe it is defined as a THROW ,

  : QUIT -56 THROW ;
  
p4_r_from --- : FCode
R> ( R: a -- a R: ) [ANS] pfe/core-ext.c

get back a value from the return-stack that had been saved there using >R . This is the traditional form of a local var space that could be accessed with R@ later. If you need more local variables you should have a look at LOCALS| which does grab some space from the return-stack too, but names them the way you like.

p4_r_fetch --- : FCode
R@ ( R: a -- a R: a ) [ANS] pfe/core-ext.c

fetch the (upper-most) value from the return-stack that had been saved there using >R - This is the traditional form of a local var space. If you need more local variables you should have a look at LOCALS| , see also >R and R> . Without LOCALS-EXT there are useful words like 2R@ R'@ R"@ R!

p4_recurse --- : FCode
RECURSE ( ? -- ? ) [ANS] pfe/core-ext.c

when creating a colon word the name of the currently-created word is smudged, so that you can redefine a previous word of the same name simply by using its name. Sometimes however one wants to recurse into the current definition instead of calling the older defintion. The RECURSE word does it exactly this.

    traditionally the following code had been in use:
    : GREAT-WORD [ UNSMUDGE ] DUP . 1- ?DUP IF GREAT-WORD THEN ;
    now use
    : GREAT-WORD DUP . 1- ?DUP IF RECURSE THEN ;
  
p4_repeat --- : FCode
REPEAT ( -- ) [ANS] [REPEAT] pfe/core-ext.c

ends an unconditional loop, see BEGIN

p4_rot --- : FCode
ROT ( a b c -- b c a ) [ANS] pfe/core-ext.c

rotates the three uppermost values on the stack, the other direction would be with -ROT - please have a look at LOCALS| and VAR that can avoid its use.

p4_r_shift --- : FCode
RSHIFT ( value# shift-count# -- value#' ) [ANS] pfe/core-ext.c

does a bitwise logical right-shift on value (ie. the value is considered to be unsigned)

p4_s_quote_execution --- : FCode_XE
'((S"))' ( -- string-ptr string-len ) [HIDDEN] pfe/core-ext.c

execution compiled by S"

p4_s_quote --- : FCode
'S"' ( [string<">] -- string-ptr string-len) [ANS] pfe/core-ext.c

if compiling then place the string into the currently compiled word and on execution the string pops up again as a double-cell value yielding the string's address and length. To be most portable this is the word to be best being used. Compare with C" and non-portable "

p4_s_to_d --- : FCode
S>D ( a# -- a,a#' | a -- a,a#' [??] ) [ANS] pfe/core-ext.c

signed extension of a single-cell value to a double-cell value

p4_sign --- : FCode
SIGN ( a# -- ) [ANS] pfe/core-ext.c

put the sign of the value into the hold-space, this is the forth-style output formatting, see HOLD

p4_s_m_slash_rem --- : FCode
SM/REM ( a,a# b# -- div-a# rem-a# ) [ANS] pfe/core-ext.c

see /MOD or FM/MOD or UM/MOD or SM/REM

p4_source --- : FCode
SOURCE ( -- buffer* IN-offset# ) [ANS] pfe/core-ext.c

the current point of interpret can be gotten through SOURCE. The buffer may flag out TIB or BLK or a FILE and IN gives you the offset therein. Traditionally, if the current SOURCE buffer is used up, REFILL is called that asks for another input-line or input-block. This scheme would have made it impossible to stretch an [IF] ... [THEN] over different blocks, unless [IF] does call REFILL

p4_space --- : FCode
SPACE ( -- ) [ANS] pfe/core-ext.c

print a single space to stdout, see SPACES

  simulate:    : SPACE  BL EMIT ;
  
p4_spaces --- : FCode
SPACES ( space-count -- ) [ANS] pfe/core-ext.c

print n space to stdout, actually a loop over n calling SPACE , but the implemenation may take advantage of printing chunks of spaces to speed up the operation.

p4_swap --- : FCode
SWAP ( a b -- b a ) [ANS] pfe/core-ext.c

exchanges the value on top of the stack with the value beneath it

p4_then --- : FCode
THEN ( -- ) [ANS] pfe/core-ext.c

does resolve a branch coming from either IF or ELSE

p4_type --- : FCode
TYPE ( string-ptr string-len -- ) [ANS] pfe/core-ext.c

prints the string-buffer to stdout, see COUNT and EMIT

p4_u_dot --- : FCode
U. ( value# -- | value -- [?] ) [ANS] pfe/core-ext.c

print unsigned number to stdout

p4_u_less_than --- : FCode
U< ( a b -- test-flag ) [ANS] pfe/core-ext.c

unsigned comparison, see <

p4_u_m_star --- : FCode
UM* ( a# b# -- a,a#' ) [ANS] pfe/core-ext.c

unsigned multiply returning double-cell value

p4_u_m_slash_mod --- : FCode
"UM/MOD" ( a,a# b# -- div-a#' mod-a#' ) [ANS] pfe/core-ext.c

see /MOD and SM/REM

p4_unloop --- : FCode
UNLOOP ( R: some,loop -- ) [ANS] pfe/core-ext.c

drop the DO .. LOOP runtime variables from the return-stack, usually used just in before an EXIT call. Using this multiple times can unnest multiple nested loops.

p4_until --- : FCode
UNTIL ( test-flag -- ) [ANS] [REPEAT] pfe/core-ext.c

ends an control-loop, see BEGIN and compare with WHILE

p4_variable --- : FCode
VARIABLE ( 'name' -- ) [ANS] [DOES: -- name* ] pfe/core-ext.c

CREATE a new variable, so that everytime the variable is name, the address is returned for using with @ and => ! - be aware that in FIG-forth VARIABLE did take an argument being the initial value. ANSI-forth does different here.

p4_while --- : FCode
WHILE ( test-flag -- ) [ANS] pfe/core-ext.c

middle part of a BEGIN .. WHILE .. REPEAT control-loop - if cond is true the code-piece up to REPEAT is executed which will then jump back to BEGIN - and if the cond is null then WHILE will branch to right after the REPEAT (compare with UNTIL that forms a BEGIN .. UNTIL loop)

p4_word --- : FCode
WORD ( delimiter-char# -- here* ) [ANS] pfe/core-ext.c

read the next SOURCE section (thereby moving >IN ) up to the point reaching $delimiter-char - the text is placed at HERE - where you will find a counted string. You may want to use PARSE instead.

p4_xor --- : FCode
XOR ( a# b# -- a#' ) [ANS] pfe/core-ext.c

return the bitwise-or of the two arguments - it may be unsafe use it on logical values. beware.

p4_left_bracket --- : FCode
[ ( -- ) [ANS] pfe/core-ext.c

leave compiling mode - often used inside of a colon-definition to make fetch some very constant value and place it into the currently compiled colon-defintion with => , or LITERAL - the corresponding unleave word is ]

p4_bracket_tick --- : FCode
['] ( [name] -- name-xt* ) [ANS] pfe/core-ext.c

will place the execution token of the following word into the dictionary. See ' for non-compiling variant.

p4_bracket_char --- : FCode
[CHAR] ( [word] -- char# ) [ANS] pfe/core-ext.c

in compile-mode, get the (ascii-)value of the first charachter in the following word and compile it as a literal so that it will pop up on execution again. See CHAR and forth-83 ASCII

p4_right_bracket --- : FCode
] ( -- ) [ANS] pfe/core-ext.c

enter compiling mode - often used inside of a colon-definition to end a previous [ - you may find a => , or LITERAL nearby in example texts.

p4_dot_paren --- : FCode
".(" ( [message] -- ) [ANS] pfe/core-ext.c

print the message to the screen while reading a file. This works too while compiling, so you can whatch the interpretation/compilation to go on. Some Forth-implementations won't even accept a => ." message" outside compile-mode while the (current) pfe does.

p4_dot_r --- : FCode
.R ( value# precision# -- | value precision# -- [??] ) [ANS] pfe/core-ext.c

print with precision - that is to fill a field of the give prec-with with right-aligned number from the converted value

p4_zero_not_equals --- : FCode
"0<>" ( 0 -- 0 | value! -- value-flag! | value -- value-flag ) [ANS] pfe/core-ext.c

returns a logical-value saying if the value was not-zero. This is most useful in turning a numerical value into a boolean value that can be fed into bitwise words like AND and XOR - a simple IF or WHILE doesn't need it actually.

p4_zero_greater --- : FCode
0> ( 0 -- 0 | value! -- value-flag! | value -- value-flag ) [ANS] pfe/core-ext.c

return value greater than zero

  simulate:    : 0> 0 > ;
  
p4_two_to_r --- : FCode
2>R ( a,a -- R: a,a ) [ANS] pfe/core-ext.c

save a double-cell value onto the return-stack, see >R

p4_two_r_from --- : FCode
2R> ( R: a,a -- a,a R: ) [ANS] pfe/core-ext.c

pop back a double-cell value from the return-stack, see R> and the earlier used 2>R

p4_two_r_fetch --- : FCode
2R@ ( R: a,a -- a,a R: a,a ) [ANS] pfe/core-ext.c

fetch a double-cell value from the return-stack, that had been previously been put there with 2>R - see R@ for single value. This can partly be a two-cell LOCALS| value, without LOCALS-EXT there are alos other useful words like 2R! R'@ R"@

p4_colon_noname_RT --- : FCode_RT
"(NONAME)" ( -- ) [HIDDEN] pfe/core-ext.c

compiled by :NONAME (see also (NEST) compiled by : (execution is identical))

p4_colon_noname --- : FCode
:NONAME ( -- C: noname,word ) [ANS] pfe/core-ext.c

start a colon nested-word but do not use CREATE - so no name is given to the colon-definition that follows. When the definition is finished at the corresponding ; the start-address (ie. the execution token) can be found on the outer cs.stack that may be stored used elsewhere then.

p4_not_equals --- : FCode
"<>" ( a b -- a-flag ) [ANS] pfe/core-ext.c

return true if a and b are not equal, see =

p4_Q_do_execution --- : FCode_XE
"((?DO))" ( a b -- ) [HIDDEN] pfe/core-ext.c

execution compiled by => ?DO

p4_Q_do --- : FCode
?DO ( end# start# | end* start* -- R: some,loop ) [ANS] pfe/core-ext.c

start a control-loop just like DO - but don't execute atleast once. Instead jump over the code-piece if the loop's variables are not in a range to allow any loop.

p4_again --- : FCode
AGAIN ( -- ) [ANS] [REPEAT] pfe/core-ext.c

ends an infinite loop, see BEGIN and compare with WHILE

p4_c_quote_execution --- : FCode_XE
'((C"))' ( -- string-bstr* ) [HIDDEN] pfe/core-ext.c

execution compiled by C" string"

p4_c_quote --- : FCode
'C"' ( [string<">] -- string-bstr* ) [ANS] pfe/core-ext.c

in compiling mode place the following string in the current word and return the address of the counted string on execution. (in exec-mode use a POCKET and leave the bstring-address of it), see S" string" and the non-portable " string"

p4_case --- : FCode
CASE ( value -- value ) [ANS] pfe/core-ext.c

start a CASE construct that ends at ENDCASE and compares the value on stack at each OF place

p4_compile_comma --- : FCode
"COMPILE," ( some-xt* -- ) [ANS] pfe/core-ext.c

place the execution-token on stack into the dictionary - in traditional forth this is not even the least different than a simple => , but in call-threaded code there's a big difference - so COMPILE, is the portable one. Unlike COMPILE , [COMPILE] and POSTPONE this word does not need the xt to have actually a name, see :NONAME

p4_convert --- : FCode
CONVERT ( a,a# string-bstr* -- a,a# a-len# ) [ANS] [OLD] pfe/core-ext.c

digit conversion, obsolete, superseded by >NUMBER

p4_endcase --- : FCode
ENDCASE ( value -- ) [ANS] pfe/core-ext.c

ends a CASE construct that may surround multiple sections of OF ... ENDOF code-portions. The ENDCASE has to resolve the branches that are necessary at each ENDOF to point to right after ENDCASE

p4_endof --- : FCode
ENDOF ( -- ) [ANS] pfe/core-ext.c

resolve the branch need at the previous OF to mark a code-piece and leave with an unconditional branch at the next ENDCASE (opened by CASE )

p4_erase --- : FCode
ERASE ( buffer-ptr buffer-len -- ) [ANS] pfe/core-ext.c

fill an area will zeros.

  2000 CREATE DUP ALLOT ERASE
  
p4_expect --- : FCode
EXPECT ( str-ptr str-len -- ) [ANS] [OLD] pfe/core-ext.c

input handling, see WORD and PARSE and QUERY the input string is placed at str-adr and its length

  in => SPAN - this word is superceded by => ACCEPT
  
p4_hex --- : FCode
HEX ( -- ) [ANS] pfe/core-ext.c

set the input/output BASE to hexadecimal

  simulate:        : HEX 16 BASE ! ;
  
p4_marker --- : FCode
MARKER ( 'name' -- ) [ANS] pfe/core-ext.c

create a named marker that you can use to FORGET , running the created word will reset the dict/order variables to the state at the creation of this name.

  : MARKER PARSE-WORD (MARKER) ;

see also ANEW which is not defined in ans-forth but which uses the MARKER functionality in the way it should have been defined.

  : MARKER PARSE-WORD (MARKER) ;
  
p4_nip --- : FCode
NIP ( a b -- b ) [ANS] pfe/core-ext.c

drop the value under the top of stack, inverse of TUCK

  simulate:        : NIP SWAP DROP ;
  
p4_of_execution --- : FCode_XE
"((OF))" ( check val -- check ) [HIDDEN] pfe/core-ext.c

execution compiled by OF

p4_of --- : FCode
OF ( value test -- value ) [ANS] pfe/core-ext.c

compare the case-value placed lately with the comp-value being available since CASE - if they are equal run the following code-portion up to ENDOF after which the case-construct ends at the next ENDCASE

p4_pad --- : FCode
PAD ( -- pad* ) [ANS] pfe/core-ext.c

transient buffer region

p4_parse --- : FCode
PARSE ( delim-char# -- buffer-ptr buffer-len ) [ANS] pfe/core-ext.c

parse a piece of input (not much unlike WORD) and place it into the given buffer. The difference with word is also that WORD would first skip any delim-char while PARSE does not and thus may yield that one. In a newer version, PARSE will not copy but just return the word-span being seen in the input-buffer - therefore a transient space.

p4_parse_word --- : FCode
PARSE-WORD ( "chars" -- buffer-ptr buffer-len ) [ANS] pfe/core-ext.c

the ANS'94 standard describes this word in a comment under PARSE, section A.6.2.2008 - quote:

Skip leading spaces and parse name delimited by a space. c-addr is the address within the input buffer and u is the length of the selected string. If the parse area is empty, the resulting string has a zero length.

If both PARSE and PARSE-WORD are present, the need for WORD is largely eliminated. Note that Forth200x calls it PARSE-NAME and clarifies that non-empty whitespace-only input is returned as a zero length string as well.

p4_pick --- : FCode
PICK ( value ...[n-1] n -- value ...[n-1] value ) [ANS] pfe/core-ext.c

pick the nth value from under the top of stack and push it note that

    0 PICK -> DUP         1 PICK -> OVER
  
p4_refill --- : FCode
REFILL ( -- refill-flag ) [ANS] pfe/core-ext.c

try to get a new input line from the SOURCE and set >IN accordingly. Return a flag if sucessful, which is always true if the current input comes from a terminal and which is always false if the current input comes from EVALUATE - and may be either if the input comes from a file

p4_restore_input --- : FCode
RESTORE-INPUT ( input...[input-len] input-len -- ) [ANS] pfe/core-ext.c

inverse of SAVE-INPUT

p4_roll --- : FCode
ROLL ( value ...[n-1] n -- ...[n-1] value ) [ANS] pfe/core-ext.c

the extended form of ROT

     2 ROLL -> ROT
  
p4_save_input --- : FCode
SAVE-INPUT ( -- input...[input-len] input-len ) [ANS] pfe/core-ext.c

fetch the current state of the input-channel which may be restored with RESTORE-INPUT later

p4_to_execution --- : FCode_XE
"((TO))" ( value -- ) [HIDDEN] pfe/core-ext.c

execution compiled by TO

p4_to --- : FCode
TO ( value [name] -- ) [ANS] pfe/core-ext.c

set the parameter field of name to the value, this is used to change the value of a VALUE and it can be also used to change the value of LOCALS|

p4_tuck --- : FCode
TUCK ( a b -- b a b ) [ANS] pfe/core-ext.c

shove the top-value under the value beneath. See OVER and NIP

  simulate:    : TUCK  SWAP OVER ;
  
p4_u_dot_r --- : FCode
U.R ( value# precision# -- ) [ANS] pfe/core-ext.c

print right-aligned in a prec-field, treat value to be unsigned as opposed to => .R

p4_u_greater_than --- : FCode
U> ( a b -- a-flag ) [ANS] pfe/core-ext.c

unsigned comparison of a and b, see >

p4_unused --- : FCode
UNUSED ( -- unused-len ) [ANS] pfe/core-ext.c

return the number of cells that are left to be used above HERE

p4_value_RT --- : FCode_RT
"((VALUE))" ( -- value ) [HIDDEN] pfe/core-ext.c

runtime compiled by VALUE

p4_value --- : FCode
VALUE ( value 'name' -- ) [HIDDEN] [DOES: -- value ] pfe/core-ext.c

CREATE a word and initialize it with value. Using it later will push the value back onto the stack. Compare with VARIABLE and CONSTANT - look also for LOCALS| and VAR

p4_within --- : FCode
WITHIN ( a# b# c# -- a-flag | a* b* c* -- a-flag ) [ANS] pfe/core-ext.c

a widely used word, returns ( b <= a && a < c ) so that is very useful to check an index a of an array to be within range b to c

p4_bracket_compile --- : FCode
[COMPILE] ( [word] -- ) [ANS] pfe/core-ext.c

while compiling the next word will be place in the currently defined word no matter if that word is immediate (like IF ) - compare with COMPILE and POSTPONE

p4_quote --- : FCode
'"' ( [string<">] -- string-bstr* ) [FTH] pfe/core-ext.c
 
     or perhaps ( [string<">] -- string-ptr string-len )

This is the non-portable word which is why the ANSI-committee on forth has created the two other words, namely S" and C" , since each implementation (and in pfe configurable) uses another runtime behaviour. FIG-forth did return bstring which is the configure default for pfe.

p4_zero_less_equal --- : FCode
0<= ( a -- flag ) pfe/core-mix.c
 
  simulate    : 0<= 0> 0= ;
  
p4_zero_greater_equal --- : FCode
0>= ( a -- flag ) pfe/core-mix.c
 
  simulate    : 0>= 0< 0= ;
  
p4_less_equal --- : FCode
<= ( a b -- flag ) pfe/core-mix.c
 
  simulate    : <= > 0= ;
  
p4_greater_equal --- : FCode
>= ( a b -- flag ) pfe/core-mix.c
 
  simulate    : >= < 0= ;
  
p4_u_less_equal --- : FCode
U<= ( a b -- flag ) pfe/core-mix.c
 
  simulate    : U<= U> 0= ;
  
p4_u_greater_equal --- : FCode
U>= ( a b -- flag ) pfe/core-mix.c
 
  simulate    : U>= U< 0= ;
  
p4_u_max --- : FCode
UMAX ( a b -- max ) pfe/core-mix.c

see MAX

p4_u_min --- : FCode
UMIN ( a b -- min ) pfe/core-mix.c

see MIN , MAX and UMAX

p4_license --- : FCode
LICENSE ( -- ) pfe/core-mix.c

show a lisence info - the basic PFE system is licensed under the terms of the LGPL (Lesser GNU Public License) - binary modules loaded into the system and hooking into the system may carry another LICENSE

  : LICENSE [ ENVIRONMENT ] FORTH-LICENSE TYPE ;
  
p4_warranty --- : FCode
WARRANTY ( -- ) pfe/core-mix.c

show a warranty info - the basic PFE system is licensed under the terms of the LGPL (Lesser GNU Public License) - which exludes almost any liabilities whatsoever - however loadable binary modules may hook into the system and their functionality may have different WARRANTY infos.

p4_dot_version --- : FCode
.VERSION ( -- ) pfe/core-mix.c

show the version of the current PFE system

  : .VERSION [ ENVIRONMENT ] FORTH-NAME TYPE FORTH-VERSION TYPE ;
  
p4_dot_date --- : FCode
.CVERSION ( -- ) pfe/core-mix.c

show the compile date of the current PFE system

  : .CVERSION [ ENVIRONMENT ] FORTH-NAME TYPE FORTH-DATE TYPE ;
  
p4_string_comma --- : FCode
STRING, ( str len -- ) pfe/core-mix.c

Store a string in data space as a counted string.

  : STRING, HERE  OVER 1+  ALLOT  PLACE ;
  
p4_parse_comma --- : FCode
PARSE, ( "chars<">" -- ) pfe/core-mix.c

Store a char-delimited string in data space as a counted string. As seen in Bawd's

  : ," [CHAR] " PARSE  STRING, ; IMMEDIATE

this implementation is much different from Bawd's

  : PARSE, PARSE STRING, ;
  
p4_parse_comma_quote --- : FCode
"PARSE,\"" ( "chars<">" -- ) pfe/core-mix.c

Store a quote-delimited string in data space as a counted string.

  : ," [CHAR] " PARSE  STRING, ; IMMEDIATE

implemented here as

  : PARSE," [CHAR] " PARSE, ; IMMEDIATE
  
p4_paren_marker --- : FCode
"(MARKER)" ( str-ptr str-len -- ) pfe/core-mix.c

create a named marker that you can use to FORGET , running the created word will reset the dict/order variables to the state at the creation of this name.

  : (MARKER) (CREATE) HERE , 
          GET-ORDER DUP , 0 DO ?DUP IF , THEN LOOP 0 , 
          ...
    DOES> DUP @ (FORGET) 
          ...
  ; 
  
p4_anew --- : FCode
ANEW ( 'name' -- ) pfe/core-mix.c

creates a MARKER if it doesn't exist, or forgets everything after it if it does. (it just gets executed).

Note: in PFE the ANEW will always work on the ENVIRONMENT-WORDLIST which has a reason: it is never quite sure whether the same DEFINITIONS wordlist is in the search ORDER that the original ANEW MARKER was defined in. Therefore, ANEW would be only safe on systems that do always stick to FORTH DEFINITIONS. Instead we will CREATE the ANEW MARKER in the ENVIRONMENT and use a simple SEARCH-WORDLIST on the ENVIRONMENT-WORDLIST upon re-run.

  \ old
  : ANEW BL WORD   DUP FIND NIP IF EXECUTE THEN   (MARKER) ;
  \ new
  : ANEW 
    PARSE-WORD  2DUP ENVIRONMENT-WORDLIST SEARCH-WORDLIST IF  EXECUTE  THEN 
    GET-CURRENT >R ENVIRONMENT-WORDLIST SET-CURRENT  (MARKER)  R> SET-CURRENT ;
  
p4_marker_RT --- : FCode_RT
"((MARKER))" ( -- ) pfe/core-mix.c

runtime compiled by MARKER

p4_strpush(const char *s) : _export void
  _strpush_ ( zstr* -- S: str* str# ) pfe/core-sub.c

push a C-string onto the SP runtime-stack, as if S" string" was used

  : _strpush_ s! _strlen_ s! ;
  
p4_pocket(void) : _export P4_GCC_MALLOC void*
  _pocket_ ( -- str* ) pfe/core-sub.c

return the next pocket for interactive string input.

  : _pocket_ _pockets@_ _pocket@_ th  _pocket@_ 1+ _pockets#_ mod to _pocket@_ ;
  
p4_dash_trailing(p4_char_t *s, int n) : _export P4_GCC_WARN_UNUSED_RESULT int
  _-trailing_ ( str* str# -- str#' ) pfe/core-sub.c

chop off trailing spaces for the stringbuffer. returns the new length, so for an internal counted string, use

    <x> dup count _-trailing_ c!
    : _-trailing_ begin dup while 
       2dup + c@ bl <> if nip exit then 
       1- repeat nip ;
  
p4_lower(p4_char_t *p, int n) : _export void
  _lower_ ( str* str# -- ) pfe/core-sub.c

_tolower_ applied to a stringbuffer

  : _lower_ 0 do dup c@ _tolower_ over c! 1+ loop drop ;
  
p4_upper(p4_char_t *p, int n) : _export void
  _upper_ ( str* str# -- ) pfe/core-sub.c

_toupper_ applied to a stringbuffer

  : _upper_ 0 do dup c@ _toupper_ over c! 1+ loop drop ;
  
p4_store_c_string(const p4_char_t *src, int n, char *dst, int max) : _export char*
  _zplaced_ ( str* str# dst* max# -- dst* ) [alias] _store_c_string_ pfe/core-sub.c

copy stringbuffer into a field as a zero-terminated string.

  : _zsplaced_ rot 2dup > if drop 1- else nip then _zplace_ ;
  
p4_pocket_c_string(const p4_char_t* src, int n) : _export P4_GCC_MALLOC char*
  _pocket_zplaced ( str* str# -- pocket* ) [alias] _pocket_c_string_ pfe/core-sub.c

store a string-span as a zero-terminated string into another pocket-pad

  : _pocket_zplaced _pocket_ _/pocket_ _zplaced_ ;
 
p4_store_filename(const p4_char_t* str, int n, char* dst, int max) : _export char*
  _zplaced_filename_ ( str* str# dst* max# -- dst* ) [alias] _store_filename_ pfe/core-sub.c

copy stringbuffer into a field as a zero-terminated filename-string, a shell-homedir like "~username" will be expanded, and the platform-specific dir-delimiter is converted in on the fly ('/' vs. '\\')

p4_pocket_filename(const p4_char_t* src, int n) : _export P4_GCC_MALLOC char*
  _pocket_fileame_ ( str* str# -- dst* ) pfe/core-sub.c

a new pocket with the given filename as asciiz

  : _pocket_filename_ _pocket_ /pocket _zplaced_filename_
  
p4_search(const char *p1, int u1, const char *p2, int u2) : _export char *
  _search_ ( str* str# key* key# -- 0 | key-in-str* ) pfe/core-sub.c

search for substring p2/u2 in string p1/u1, returns null if not found or a pointer into str*,str# that has lenght of key#

p4_match(const p4char *pattern, const p4char *str, int len, int ic) : _export int
  _match_ ( zpattern* zstring* ignorecase? -- yes? ) pfe/core-sub.c

Match string against pattern. Pattern knows wildcards `*' and `?' and `\' to escape a wildcard.

p4_udiv(p4ucell num, p4ucell denom) : _export P4_GCC_CONST udiv_t
  _U/_ pfe/core-sub.c

unsigned divide procedure, single prec

p4_fdiv(p4cell num, p4cell denom) : _export P4_GCC_CONST fdiv_t
  _/_ pfe/core-sub.c

floored divide procedure, single prec

p4_u_d_div(p4udcell *ud, p4ucell denom) : _export p4ucell
  _ud/_ pfe/core-sub.c

Divides *ud by denom, leaves result in *ud, returns remainder. For number output conversion: dividing by BASE.

p4_u_d_mul(p4udcell *ud, p4ucell w, p4ucell c) : _export void
  _ud*_ pfe/core-sub.c

Computes *ud * w + c, where w is actually only half of a cell in size. Leaves result in *ud. For number input conversion: multiply by BASE and add digit.

p4_dig2num(p4_char_t c, p4ucell *n, p4ucell base) : _export int
  _dig>num_ ( c n* base -- ?ok ) pfe/core-sub.c

Get value of digit c into *n, return flag: valid digit.

p4_num2dig(p4ucell n) : _export P4_GCC_CONST char
  _num2dig_ ( val -- c ) pfe/core-sub.c

make digit

p4_number_question(const p4_char_t *p, p4ucell n, p4dcell *d) : _export int
  _?number_ ( str* str# dcell* -- ?ok ) pfe/core-sub.c

try to convert into number, see => ?NUMBER

p4_str_ud_dot_r(p4udcell ud, char *p, int w, int base) : _export char *
  _ud.r_ ( d,d str* str# base -- str* ) pfe/core-sub.c

This is for internal use only (SEE and debugger), The real UD.R etc. words uses HOLD and the memory area below PAD

p4_str_d_dot_r(p4dcell d, char *p, int w, int base) : _export char *
  _d.r_ ( d,d str* str# base -- str* ) pfe/core-sub.c

This is for internal use only (SEE and debugger), The real UD.R etc. words use HOLD and the memory area below PAD

p4_str_dot(p4cell n, char *p, int base) : _export char *
  _._ ( i str* str# base -- str* ) pfe/core-sub.c

This is for internal use only (SEE and debugger), The real => . etc. words use HOLD and the memory area below PAD

p4_outc(char c) : _export void
  _outc_ ( char -- ) [alias] _outc pfe/core-sub.c

emit single character, (output adjusting the OUT variable, see _putc_ to do without)

  : _emit_ _putc_ _?xy_ drop out ! ;
  
p4_outf(const char *s,...) : int
  _outf_ ( ... zstr* -- n# ) pfe/core-sub.c

type a string with formatting (output adjusting the OUT variable, see _puts_ and _outs_ )

  : _outf_ 0x200 lbuffer: buf[]  buf[] _vsprintf_  buf[] _outs_ ;
  
p4_type_on_line(const p4_char_t *str, p4cell len) : _export void
  _typeline_ ( str* str# -- ) pfe/core-sub.c

type counted string to terminal, if it does not fit in full on the current line, emit a CR before (output adjusting the OUT variable, see _type_ and _outs_ )

  : _typeline_ out @ over + cols @ > if cr then _type_ ;
  
p4_emits(int n, const char c) : _export void
  _emits_ ( n# ch -- ) pfe/core-sub.c

type a string of chars by repeating a single character which is usually a space, see SPACES (output adjusting the OUT variable, see _type_ and _outs_ )

  : _emits_ swap 0 do dup _putc_ loop drop _flush_ _?xy_ drop out ! ;
  
p4_tab(int n) : _export void
  _tab_ ( n# -- ) pfe/core-sub.c

type a string of space up to the next tabulator column (output adjusting the OUT variable, see _emits and _typeonline )

  : _tab_ dup out @ - swap mod bl _emits_ ;
  
p4_dot_line(p4_File *fid, p4cell n, p4cell l) : _export void
  _.line_ ( file* block# line# -- ) pfe/core-sub.c
p4_query --- : FCode
QUERY ( -- ) pfe/core-sub.c

source input: read from terminal using _accept_ with the returned string to show up in TIB of /TIB size.

p4_next_line(void) : _export p4_bool_t
 ... pfe/core-sub.c
p4_size_saved_input(void) : _export p4ucell
  _size_saved_input_ ( -- iframe-size ) pfe/core-sub.c
p4_link_saved_input(void *p) : _export void
  _link_saved_input_ ( iframe* -- ) pfe/core-sub.c

see SAVE-INPUT

p4_unlink_saved_input(void *p) : _export void
  _unlink_saved_input_ ( iframe* -- ) pfe/core-sub.c

see RESTORE-INPUT

p4_skip_delimiter(char del) : _export void
  _skip_delimiter_ ( del -- ) pfe/core-sub.c

SKIP-DELIMITER

p4_word_parse(char del) : _export p4_cell_t
  _word:parse_ ( delim -- ) pfe/core-sub.c
p4_word_to_here(void) : _export char*
  _word>here_ ( -- here* ) pfe/core-sub.c

complement _word:parse_ to arrive at the normal WORD implementation will also ensure the string is zero-terminated - this makes a lot of operations easier since most forth function can receive a string-span directly but some need a string-copy and that is usually because it has to be passed down into a C-defined function with zerotermined string. Just use p4_HERE+1 (which is also the returnvalue of the p4_word_to_here function!) to have the start of the zero-terminated string. Note that the p4_word_to_here function may throw with P4_ON_PARSE_OVER if the string is too long (it has set *DP=0 to ensure again that THROW will report PFE.word. as the offending string)

p4_debug --- : FCode
DEBUG ( "word" -- ) [FTH] pfe/debug-ext.c

this word will place an debug-runtime into the CFA of the following word. If the word gets executed later, the user will be prompted and can decide to single-step the given word. The debug-stepper is interactive and should be self-explanatory. (use NO-DEBUG to turn it off again)

p4_no_debug --- : FCode
NO-DEBUG ( "word" -- ) [FTH] pfe/debug-ext.c

the inverse of " DEBUG word "

p4_paren_see --- : FCode
(SEE) ( some-xt* -- ) [FTH] pfe/debug-ext.c

decompile the token-sequence - used by SEE name

p4_addr_to_name(const p4_byte_t* addr) : _export p4_namebuf_t const *
  ADDR>NAME ( word-addr* -- word-nfa*!' | 0 ) [FTH] pfe/debug-ext.c

search the next corresponding namefield that address is next too. If it is not in the base-dictionary, then just return 0 as not-found.

p4_come_back --- : FCode
COME_BACK ( -- ) [FTH] pfe/debug-ext.c

show the return stack before last exception along with the best names as given by ADDR>NAME

p4_make_wordlist(p4char* nfa) : _export p4_Wordl *
  pfe/dict-sub.c

create a word list in the dictionary

p4_forget_dp --- : FCode
((FORGET)) pfe/dict-sub.c

remove words from dictionary, free dictionary space, this is the runtime helper of (FORGET)

p4_forget(p4_byte_t* above) : _export void
  (FORGET) pfe/dict-sub.c

forget anything above address

p4_forget_word(const char *name, p4cell id, p4code ccode, p4cell what) : _export p4_namebuf_t*
 ... pfe/dict-sub.c
p4_tick_nfa(void) : _export p4char *
 ... pfe/dict-sub.c
p4_tick_cfa(void) : _export p4xt
 ... pfe/dict-sub.c
p4_only_RT --- : FCode
ONLY ( -- ) pfe/dict-sub.c

the only-vocabulary is special. Calling it will erase the search ORDER of vocabularies and only allows to name some very basic vocabularies. Even ALSO is not available.

  example:
    ONLY FORTH ALSO EXTENSIONS ALSO DEFINITIONS
  
p4_forth_RT --- : FCode
FORTH ( -- ) pfe/dict-sub.c
 
  : FORTH FORTH-WORDLIST CONTEXT ! ;
  
p4_dlinit(void) : _export int
  dlfcn: init dl symbol table, dl error pfe/dl-dlfcn.c
p4_dlerror(void) : _export const char*
  dlfcn: describe last dl-error pfe/dl-dlfcn.c
p4_dlopenext(const char* name) : _export void*
  dlfcn: load shared-object into program codespace pfe/dl-dlfcn.c
p4_dlclose(const void* lib) : _export int
  dlfcn: remove shared-object from program codespace pfe/dl-dlfcn.c
p4_dlsym(const void* lib, const char* symbol) : _export void*
  dlfcn: find symbol in loaded object pfe/dl-dlfcn.c
p4_dladdr(void* addr, int* offset) : _export char*
  dlfcn: find name for address pfe/dl-dlfcn.c
p4_slot_use(int* var) : int
  pfe/dl-ext.c

request a slot index. The index is written to the variable arg-address. if the arg-address contains a value != 0, we check if that specific slot index is free for assignment - or already assigned to this variable. a slot_use can be done for the same slot-variable multiple times, which will increase a use-counter. Call slot_unuse correspondingly.

p4_slot_unuse(int* var) : int
 ... pfe/dl-ext.c
p4_paren_loadm --- : FCode
(LOADM) ( module-bstr* -- module-sucess# ) [FTH] pfe/dl-ext.c
p4_loadm --- : FCode
LOADM ( "filename" -- ) [FTH] pfe/dl-ext.c

dlmap the shared object (or share an already mapped object) and run the per-thread initialization code. This is the user-convenient function, otherwise use (LOADM)

  simulate:
    : LOADM  BL WORD   
      ((IS_MODULE_LOADED)) IF EXIT THEN 
      HERE (LOADM)  0= IF ." -- load failed: " HERE COUNT TYPE CR THEN ;
  
p4_local_dlsym --- : FCode
LOCAL-DLSYM ( [symbol] -- symbol-addr ) [FTH] [EXEC] pfe/dl-ext.c

lookup the symbol that follows and leave the address (or null)

p4_local_dlcall --- : FCode
LOCAL_DLCALL ( x...[8] [symbol] -- x...[8] ) [FTH] [EXEC] pfe/dl-ext.c

does not do any stack changes, the caller must clean up the stack himself. You don't even get the return value (sigh)

p4_lt_dlinit --- : FCode
lt_dlinit ( -- dlinit-ior# ) [FTH] pfe/dl-ext.c

initialiize library, usually open the program itself so that its handles can be found under "0"

p4_lt_dlopenext --- : FCode
lt_dlopenext ( module-ptr module-len -- module-dl-handle*! | 0 ) [FTH] pfe/dl-ext.c

walk the searchpath for dlopen and try to open a binary module under the given name with the usual file extension for the current system.

p4_lt_dlsym --- : FCode
lt_dlsym ( symbol-ptr symbol-len module-dl-handle* -- symbol*! | 0 ) [FTH] pfe/dl-ext.c

try to find the name in the binary module denoted by its handle .. if handle is null, use the main body of the program

p4_lt_dlcose --- : FCode
lt_dlclose ( module-dl-handle* -- module-ior# ) [FTH] pfe/dl-ext.c

close handle that was returned by lt_dlopenext

p4_lt_dlerror --- : FCode
lt_dlerror ( -- dlerror-zstr* ) pfe/dl-ext.c

returns string describing the last dlerror as for lt_dlopenext and lt_dlsym

p4_two_constant_RT --- : FCode_RT
(2CONSTANT) ( -- x1 x2 ) pfe/double-ext.c

runtime portion of 2CONSTANT

p4_two_constant --- : FCode
2CONSTANT ( x1 x2 "name" -- ) pfe/double-ext.c

create a word that contains the specified twocell number in its body. when the name is executed, these numbers are left on the stack

    12. 2CONSTANT X .s 
    <emtpy stack> ok
    X .s
    0 12 ok
  
p4_two_literal_execution --- : FCode_XE
(2LITERAL) ( -- x1 x2 ) pfe/double-ext.c

runtime portion of 2LITERAL

p4_two_literal --- : FCode
2LITERAL ( x1 x2 -- ) immediate pfe/double-ext.c

compile a double-cell number to the current definition. When run, the doubele-cell is left on the stack for execution.

    ( -- x1 x2 )

(in most configurations this word is statesmart and it will do nothing in interpret-mode. See 2LITERAL, for a non-immediate variant)

p4_two_variable --- : FCode
2VARIABLE ( -- ) pfe/double-ext.c

CREATE a new variable definition. When executed leave the >BODY address on stack. In pfe, the data area of a 2VARIABLE is ERASEd initially.

p4_d_plus --- : FCode
D+ ( d1.ud1 d2.ud2 -- d3.ud3 ) pfe/double-ext.c

the double-cell sum operation ( + )

p4_d_minus --- : FCode
D-( d1.ud1 d2.ud2 -- d3.ud3 ) pfe/double-ext.c

the double-cell diff operation ( - )

p4_d_dot_r --- : FCode
D.R ( d1.d1 n -- ) pfe/double-ext.c

aligned output for a double-cell number ( => .R )

p4_d_dot --- : FCode
D. ( d1.d1 -- ) pfe/double-ext.c

freefield output for a double-cell number ( => . )

p4_d_zero_less --- : FCode
D0< ( d1.d1 -- flag ) pfe/double-ext.c

the double-cell less-than-zero operation ( 0< )

p4_d_zero_equals --- : FCode
D0= ( d1.d1 -- flag ) pfe/double-ext.c

the double-cell equal-to-zero operation ( 0= )

p4_d_two_star --- : FCode
D2* ( d1.d1 -- d1.d1' ) pfe/double-ext.c

the double-cell arithmetic shiftleft-by-1 operation ( 2* )

p4_d_two_slash --- : FCode
D2/ ( d1.d1 -- d1.d1' ) pfe/double-ext.c

the double-cell arithmetic shiftright-by-1 operation ( 2/ )

p4_d_less --- : FCode
D< ( d1.d1 d2.d2 -- flag ) pfe/double-ext.c

the double-cell is-less operation ( < )

p4_d_to_s --- : FCode
D>S ( d.d -- n ) pfe/double-ext.c

result is the numeric equivalent of d. If the double number was greater than what could fit into a single cell number, the modulo cellsize will be left since the higher-significant bits are just DROPed

p4_d_equals --- : FCode
D= ( d1.d1 d2.d2 -- flag ) pfe/double-ext.c

the double-cell is-equal operation ( = )

p4_d_abs --- : FCode
DABS ( d1.d1 -- d1.d1' ) pfe/double-ext.c

the double-cell abs operation ( ABS )

p4_d_max --- : FCode
DMAX ( d1.d1 d2.d2 -- d1.d1|d2.d2 ) pfe/double-ext.c

the double-cell max operation ( MAX )

p4_d_min --- : FCode
DMIN ( d1.d1 d2.d2 -- d1.d1|d2.d2 ) pfe/double-ext.c

the double-cell max operation ( MIN )

p4_d_negate --- : FCode
DNEGATE ( d1.d1 -- d1.d1' ) pfe/double-ext.c

the double-cell arithmetic negate operation ( NEGATE )

p4_m_star_slash --- : FCode
"M*\/" ( d1.d1 n1 +n2 -- d2.d2 ) pfe/double-ext.c

the double-cell multiply-divide operation using a triple-cell intermediate result for * ( *\/ )

p4_m_plus --- : FCode
"M+" ( d1.d1 n1 -- d2.d2 ) pfe/double-ext.c

the double-cell mixed-operand sum operation ( + / D+ )

p4_two_rot --- : FCode
2ROT ( d1,d1 d2,d2 d3,d3 -- d2,d2 d3,d3 d1,d1 ) pfe/double-mix.c

the double-cell ROT operation. actively moves six cells, i.e.

    ( x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2 )
  
p4_d_u_less --- : FCode
DU< ( d1,d1 d2,d2 -- flag ) pfe/double-mix.c

the double-cell unsigned-is-less operation ( U< )

p4_literal_comma --- : FCode
LITERAL, ( value -- ) pfe/double-mix.c

take the value from stack (or cs-stack) and compile a runtime-code and the value as for LITERAL ... this word is never state-smart, it is not immediate, and has therefore no complications with POSTPONE (compare also with COMPILE, to make a call-stub with an exectoken)

p4_two_literal_comma --- : FCode
2LITERAL, ( x1,x2 -- ) pfe/double-mix.c

take the double-value from stack (or cs-stack) and compile a runtime-code and the value as for 2LITERAL ... this word is never state-smart, it is not immediate, and has therefore no complications with POSTPONE (compare also with COMPILE, to make a call-stub with an exectoken)

p4_dcells --- : FCode
DCELLS ( x -- x' ) pfe/double-mix.c

computes the number of address units for the specified number of double-cells

  : DCELLS CELLS 2* ;
  
p4_d_shiftleft --- : FCode
DLSHIFT ( x1,x2 y -- z1,z2 ) pfe/double-mix.c

shift-left a double-cell value. The shift-count is given as a single-cell.

p4_d_shiftright --- : FCode
DRSHIFT ( x1,x2 y -- z1,z2 ) pfe/double-mix.c

shift-right a double-cell value. The shift-count is given as a single-cell. This is an arithmetic shift as for a signed double-cell value.

p4_um_plus(p4dcell * a, p4ucell b) : _export void
  add b to a pfe/double-sub.c
p4_d_ummul(p4ucell a, p4ucell b) : _export p4udcell
  unsigned multiply, mixed precision pfe/double-sub.c
p4_d_mmul(p4cell a, p4cell b) : _export p4dcell
  signed multiply, mixed precision pfe/double-sub.c
p4_d_umdiv(p4udcell num, p4ucell denom) : _export udiv_t
  unsigned divide procedure, mixed precision pfe/double-sub.c
p4_d_smdiv(p4dcell num, p4cell denom) : _export fdiv_t
  symmetric divide procedure, mixed precision pfe/double-sub.c
p4_d_fmdiv(p4dcell num, p4cell denom) : _export fdiv_t
  floored divide procedure, mixed precision pfe/double-sub.c
p4_empty_str --- : FCode
EMPTY$ ( $: -- empty$ ) pfe/dstrings-ext.c

Push the MSA of a fixed, external representation of the empty string onto the string stack. "empty-string"

p4_newline_str --- : FCode
\n$ ( $: -- newline$ ) pfe/dstrings-ext.c

Push the MSA of a fixed, external string whose body is the Unix newline character onto the string stack. "newline-string"

p4_parens_m_store --- : FCode
(M!) ( a.s msa -- ) pfe/dstrings-ext.c

(M!) is the same as Wil Baden's PLACE, except it assumes the buffer address msa to be aligned, and stores the ANS Forth string a.s as a measured string, zero-filled to trailing alignment. As with PLACE, it is assumed that the mstring copy does not clobber the old string, and there is no check for room starting at msa. "parens-m-store"

p4_parse_to_s --- : FCode
PARSE>S ( [ccc] char -- addr len ) pfe/dstrings-ext.c

Parse the input stream up to the first occurrence of char, which is parsed away. If executing in compilation mode, append run-time semantics to the current definition that leaves the ANS Forth string representation on the stack. In interpretation mode, leave the ANS Forth string representation for a stored copy, which may be transient in the style of S". In either mode, the format of the stored string is implementation dependent. "parse-to-s"

NOTE: The interpreted copy is a nontransient in this implementation, and both copies are mstrings.

p4_s_back_tick --- : FCode
S` ( [ccc<`>] -- addr len ) pfe/dstrings-ext.c

An immediate version of parse>s where the delimiter is `. In particular, the stored string in interpret mode is not transient. "s-back-tick"

p4_m_comma_s --- : FCode
M,S ( addr len -- addr' len ) pfe/dstrings-ext.c

ALLOT room and store the ANS Forth string into aligned data space as an mstring, leaving data space zero-filled to alignment; and leave the length and new body address. It is assumed that len is unsigned. An error is thrown if len is larger than the system parameter MAX_DATA_STR. "m-comma-s"

NOTE: MAX_DATA_STR is returned by

    S" /SCOPY" ENVIRONMENT?
 

NOTE: M,S differs from STRING, in Wil Baden's Tool Belt in that it stores an aligned, measured string with zero-filled alignment instead of a counted string, and it leaves the ANS Forth string representation of the stored string.

p4_m_count_fetch --- : FCode
MCOUNT@ ( msa -- count ) pfe/dstrings-ext.c

Fetch the count of the mstring at msa. "m-count-fetch"

p4_m_count_store --- : FCode
MCOUNT! ( count msa -- ) pfe/dstrings-ext.c

Store the count in the measured string count field at msa, without checking that it fits. "m-count-store"

p4_m_count --- : FCode
MCOUNT ( msa -- body.addr count ) pfe/dstrings-ext.c

Convert the mstring MSA to its ANS Forth string representation. "m-count"

p4_minus_m_count --- : FCode
-MCOUNT ( addr len -- msa ) pfe/dstrings-ext.c

Convert the ANS Forth representation of an mstring to its MSA. "minus-m-count"

p4_zero_strings --- : FCode
0STRINGS ( -- ) pfe/dstrings-ext.c

Set all string variables holding bound string values in string space to the empty string, and clear string space, including the string buffer, string stack, and string stack frames. "zero-strings"

NOTE: If used for under the hood development, this word must be executed only when string space is in a valid state.

p4_str_garbage_Q --- : FCode
$GARBAGE? ( -- flag ) pfe/dstrings-ext.c

Leave true if there is garbage in the current string space. Not normally used, since garbage collection is transparent. "string-garbage-question"

p4_str_gc_off --- : FCode
$GC-OFF ( -- ) pfe/dstrings-ext.c

Disable garbage collection in the current string space. An error will be thrown if garbage collection is attempted. "string-g-c-off"

p4_str_gc_on --- : FCode
$GC-ON ( -- ) pfe/dstrings-ext.c

Enable garbage collection in the current string space. This is the default. "string-g-c-on"

p4_str_gc_lock_fetch --- : FCode
$GC-LOCK@ ( -- flag ) pfe/dstrings-ext.c

Fetch the dstring garbage collection "off" state. Intended for saving the off state for later restoration after a usage of $GC-ON or $GC-OFF. "string-g-c-lock-fetch"

p4_str_gc_lock_store --- : FCode
$GC-LOCK! ( flag -- ) pfe/dstrings-ext.c

Set the dstring garbage collection "off" state according to flag. Intended for restoring the off state previously fetched by $GC-LOCK@. "string-g-c-lock-fetch"

p4_str_unused --- : FCode
$UNUSED ( -- u ) pfe/dstrings-ext.c

Leave the number of bytes available for dynamic strings and string stack entries in the string buffer. "string-unused"

p4_collect_str_garbage --- : FCode
COLLECT-$GARBAGE ( -- collected-flag ) pfe/dstrings-ext.c

If string space is not marked as containing garbage, return false. If there is garbage, throw an error when garbage collection is disabled. Otherwise remove the garbage and return true. Garbage collection is "transparent", so the user would not normally use this word. "collect-string-garbage"

p4_make_str_space --- : FCode
MAKE-$SPACE ( size #frames -- addr ) pfe/dstrings-ext.c

Allocate and initialize a string space with size bytes available for the string buffer including the string stack, and with a string frame stack for frame description entries holding up to #frames. The size is rounded up to cell alignment, and the buffer begins and ends with cell alignment. Return addr, the address of the string space. The standard word FREE with addr as input can be used to release the space. "make-string-space"

p4_slash_str_buf --- : FCode
/$BUF ( -- u ) pfe/dstrings-ext.c

Leave the size in address units allocated for the current string buffer. "slash-string-buf"

p4_max_num_str_frames --- : FCode
MAX-#$FRAMES ( -- u ) pfe/dstrings-ext.c

Leave the number of string frames allowed on the string frame stack for the current string space. "max-number-string-frames"

p4_str_store --- : FCode
$! ( $var.dfa $: a$ -- ) pfe/dstrings-ext.c

Store the string MSA on the string stack in the variable whose DFA is on the parameter stack. "string-store"

NOTES: The only situation in which $! copies the string value is when it is a bound string already stored in another variable. In that case, the new copy is the one that is stored in the variable. In particular, external strings are not copied.

If the string value held by the string variable on entry is a bound string that is also referenced deeper on the string stack, its back link is reset to point to the deepest string stack reference. If it is a bound string not deeper on the string stack and not identical to the input string, its back link is set to zero, making it garbage. If it is an external string, its MSA in the variable is simply written over by that popped from the string stack.

p4_str_fetch --- : FCode
$@ ( $var.pfa -- $: a$ ) pfe/dstrings-ext.c

Leave the MSA of the string held by the string variable. "string-fetch"

p4_str_quote --- : FCode
$" ( [ccc<">] -- $: str ) pfe/dstrings-ext.c

Parse ccc delimited by " (double quote) and store it in data space as an mstring. If interpreting, leave the MSA on the string stack. If compiling, append run-time semantics to the current definition that leaves the MSA on the string stack. A program should not alter the stored string. An error is thrown if the quoted string length is larger than the system parameter MAX_DATA_STR (see SM,). "string-quote"

NOTE: In contrast to S", the string stored by $" when interpreting is not transient.

The implementation is based on PFE code for S".

p4_str_back_tick --- : FCode
$` ( [ccc<`>] -- $: str ) pfe/dstrings-ext.c

Parse ccc delimited by ` (back-tick). This is "$"" with back tick instead of double quote as the delimiter. "string-back-tick"

p4_str_constant --- : FCode
$CONSTANT ( "name" $: a$ -- ) pfe/dstrings-ext.c

Create a definition for "name" with the execution semantics "name" execution: ($: -- a$ )

It is assumed that the input string resides as a measured, unchanging string outside of string space. "string-constant"

For example:

    $" This is a sample string." $constant sample$
  
p4_str_variable --- : FCode
$VARIABLE ( "name" -- ) pfe/dstrings-ext.c
 
    "name" execution:	( -- dfa )
 

Create an ordinary Forth variable and initialize it to the address of a fixed, external, measured representation of the empty string, such as that pushed onto the string stack by EMPTY$. "string-variable""

p4_parse_to_str --- : FCode
PARSE>$ ( [ccc] char -- $: ccc$ ) pfe/dstrings-ext.c

Parse the input stream up to the first occurrence of char, which is parsed away, and store the string as an external measured string. If executing in compilation mode, append run-time semantics to the current definition that leaves the MSA on the string stack. In interpretation mode, leave the MSA on the string stack, where the stored copy, unlike PARSE>S, is required to be nontransient.

p4_str_two_drop --- : FCode
$2DROP ( $: a$ b$ -- ) pfe/dstrings-ext.c

Drop the two topmost string stack entries, marking them as garbage if appropriate. "string-two-drop"

p4_str_two_dup --- : FCode
$2DUP ( $: a$ b$ -- a$ b$ a$ b$ ) pfe/dstrings-ext.c

Leave copies of the two topmost string stack entries. The string values are not copied. "string-two-dupe"

p4_str_depth --- : FCode
$DEPTH ( -- n ) pfe/dstrings-ext.c

Leave the number of items on the string stack. "string-depth"

p4_str_drop --- : FCode
$DROP ( $: a$ -- ) pfe/dstrings-ext.c

Drop the topmost string stack entry, marking it as garbage if it is initially bound to the top of the string stack. "string-drop"

p4_str_dup --- : FCode
$DUP ( $: a$ -- a$ a$ ) pfe/dstrings-ext.c

Leave a copy of the topmost string stack entry. The string value is not copied. "string-dupe"

p4_str_nip --- : FCode
$NIP ($: a$ b$ -- b$ ) pfe/dstrings-ext.c

Drop the next to top item from the string stack. "string-nip"

NOTE: Because of essential string space bookkeeping, the system level implementation can be little more efficient than the high-level definition:

    : $NIP  $SWAP $DROP ;
  
p4_str_over --- : FCode
$OVER ( $: a$ b$ -- a$ b$ a$ ) pfe/dstrings-ext.c

Leave a copy of the next most accessible string stack entry on top of the string stack. The string value is not copied. "string-over"

p4_str_pick --- : FCode
$PICK ( u $: au$ ... a0$ -- au$ ... a0$ au$ ) pfe/dstrings-ext.c

Copy the u-th string stack entry to the top of the string stack. The string value is not copied. Throw an error if the input string stack does not have at least u+1 items. "string-pick"

p4_str_swap --- : FCode
$SWAP ( $: a$ b$ -- b$ a$ ) pfe/dstrings-ext.c

Exchange the two most accessible strings on the string stack. Throw an error if there are less than two strings on the stack. Neither string value is copied. "string-swap"

p4_str_exchange --- : FCode
$EXCHANGE ( i j -- ) pfe/dstrings-ext.c

($: maxth$ ... minth$ ... -- minth$ ... maxth$ ... ) Exchange the ith and jth strings on the string stack, where the top is the 0th. Throw an error if there are not at least max[i,j] + 1 strings on the stack. Neither string value is copied. "string-exchange"

p4_str_s_from --- : FCode
$S> ( $: a$ -- S: a.s ) pfe/dstrings-ext.c

Drop a$ from the string stack and leave it as a ANS Forth string a.s, without copying. "string-s-from"

WARNING: If a$ is a bound string, it may move or disappear at the next garbage collection, making a.s invalid. This can be avoided by sandwiching sections of code where this could occur between $GC-OFF and $GC-ON.

p4_str_comma_s --- : FCode
$,S ( $: a$ -- S: a.s ) pfe/dstrings-ext.c

Drop a$ from the string stack, copy it into data space as a measured string, and leave it as an ANS Forth string a.s. An error is thrown if the string length is larger than the system parameter MAX_DATA_STR (see M,S). "string-comma-s"

p4_str_s_fetch --- : FCode
$S@ ( $: a$ -- a$ S: a.s ) pfe/dstrings-ext.c

Leave the string stack unchanged, and leave the string body address and length on the data stack. "string-s-fetch"

WARNING: If a$ is a bound string, it may move at the next garbage collection, making a.s invalid. This can be avoided by sandwiching sections of code where this could occur between $GC-OFF and $GC-ON.

p4_str_tuck --- : FCode
$TUCK ($: a$ b$ -- b$ a$ b$ ) pfe/dstrings-ext.c

Copy the top string stack item just below the second item. The string value is not copied. "string-tuck"

NOTE: Because of essential string space bookkeeping, the system level implementation can be little more efficient than the high-level definition:

    : $TUCK  $SWAP $OVER ;
  
p4_to_str_s --- : FCode
>$S ( a.s -- $: a$ ) pfe/dstrings-ext.c

Push the external ANS Forth string a.s onto the string stack, without copying the string value into the string buffer. It is an unchecked error if the Forth string a.s is not stored as an external measured string. "to-string-s"

WARNING: If the string value of a.s is actually in the string buffer and not external, the push operation may generate a garbage collection that invalidates its MSA.

p4_to_str_s_copy --- : FCode
>$S-COPY ( a.s -- $: a$ ) pfe/dstrings-ext.c

Copy the external string value whose body address and count are on the parameter stack into the string buffer and push it onto the string stack. Errors are thrown if the count is larger than MAX_MCOUNT, if there is not enough room in string space, even after garbage collection, or if there is an unterminated string concatenation. The input external string need not exist as a measured string. "to-string-s-copy"

NOTE: MAX_MCOUNT is the largest size the count field of a measured string can hold, e.g., 255, 64K-1, or 4,096M-1. It is returned by:

    S" /DYNAMIC-STRING" ENVIRONMENT?
 

WARNING: This word should not be used when the input string is a bound string because the copy operation may generate a garbage collection which invalidates its MSA.

p4_str_plus --- : FCode
$+ ($: a$ -- ) pfe/dstrings-ext.c

If a$ is the empty string, drop it and do nothing else.

In particular, do not start a new concatenation, which would lock string space against new nonconcatenating copies.

Otherwise append the string body to the end of the string currently being concatenated as the last string in the string buffer, and update its count field. If there is no concatenating string, start one. An error is thrown if the size of the combined string would be larger than MAX_MCOUNT or if there is not enough room in string space even after a garbage collection.

If garbage collection occurs, a$ remains valid even when it is in the string buffer.

When there is a concatenating string, concatenation is the only basic string operation that can copy a string into the string buffer. "string-plus"

p4_parse_s_plus --- : FCode
PARSE-S+ ( [ccc] char -- ) pfe/dstrings-ext.c

Parse the input stream up to the first occurrence of char, which is parsed away. If executing in compilation mode, append run-time semantics to the current definition that concatenates the characters parsed from the string. Otherwise concatenate the characters. "parse-s-plus"

p4_endcat --- : FCode
ENDCAT ( -- $: cat$ | empty$ ) pfe/dstrings-ext.c

If there is no concatenating string, do nothing but leave the empty string. If there is, leave it as a string bound to the top of the string stack, and terminate concatenation, permitting normal copies into the string buffer. "end-cat"

p4_str_plus_quote --- : FCode
$+" ( [ccc] -- ) pfe/dstrings-ext.c

This word is immediate. In compilation mode it appends run-time semantics to the current definition that concatenates the quoted string according to the specification for $+. In interpretation mode it concatenates the string. An error is thrown if the length of the quoted string is longer than the system parameter MAX_DATA_STR (see M,S). "string-plus-quote"

p4_str_plus_back_tick --- : FCode
$+` ( [ccc] -- ) pfe/dstrings-ext.c

The same as $+" but with back tick instead of double quote as delimiter. "string-plus-back-tick"

p4_num_str_args --- : FCode
#$ARGS ( -- u ) pfe/dstrings-ext.c

Leave the number of entries in the topmost string frame. Throw an error if the frame stack is empty. "number-string-args"

p4_str_args_brace --- : FCode
$ARGS{ ( arg1'$ ... argN'$ "arg1 ... argN <}>" -- ) pfe/dstrings-ext.c
 
     compilation: ( -- $: arg1$ ... argN$ )

Immediate and compilation-only.

Copy the argument strings across lines to the string buffer, push them onto the string stack with "argN" the most accessible, and make them into the top compile-time string stack frame. Compile the run-time code to make an argument frame out of the N most accessible run-time string stack entries. Inform the system text interpreter that it should compile run-time code for any white-space delimited argument encountered in the text of the definition, that concatenates the corresponding string in the run-time frame. At the semicolon terminating the definition, drop the compile-time argument frame and compile code to drop the run-time argument frame.

The code between $ARGS{ ... } and the terminating semicolon is not allowed to make a net change in the string stack depth, because that would interfere with the automatic dropping of the string argument frame at the semicolon. "string-args-brace"

Syntax for defining a string macro GEORGE:

 
      : george  ($: a$ b$ c$ -- cat$ )
        $ARGS{ arg1 arg2 arg3 }
        cat" This is arg1:  " arg1 cat" ." ENDCAT $. ;
 

The blank following the last argument is required. For a macro with no arguments, $ARGS{ } does nothing but add useless overhead and should be omitted. Two of the arguments in this example are ignored and could have been left out. Note that ENDCAT would not be legal in this word without something like $. to remove the concatenated string from the string stack before the terminating semicolon. It is normal to use an $ARGS{ } word as a step in a concatenation that is terminated elsewhere.

Sample syntax using the string macro george:

 
      $" bill"  $" sue"  $" marie"  george $.
 

The resulting display is:

 
      This is arg1:  bill.
 

NOTE: Macro argument labels must be distinct from each other and from any local labels that appear in the same definition, and there is no check for that.

NOTE: At the moment the semantics of $ARGS{ is undefined before DOES>.

p4_str_frame --- : FCode
$FRAME ( u -- ) pfe/dstrings-ext.c

Push the description of a string stack frame starting at the top of the string stack and containing u entries onto the string frame stack. Errors are thrown if the frame stack would overflow or if the depth of the string stack above the top frame, if there is one, is less than u. The value u = 0 is allowed. "string-frame"

NOTE: This implementation pushes u and the string stack pointer onto the frame stack.

p4_str_frame_depth --- : FCode
$FRAME-DEPTH ( -- u ) pfe/dstrings-ext.c

Leave the number of string frames currently on the string frame stack. "string-frame-depth"

p4_drop_str_frame --- : FCode
DROP-$FRAME ($: frame*$ i*$ -- i*s ) pfe/dstrings-ext.c

Drop the topmost string frame from the string frame stack, and the corresponding strings, frame*$, from the string stack. An error is thrown if either stack would underflow. The cases where the frame has zero entries on the string stack and/or there are zero or more items on the string stack above the top frame item are handled properly. "drop-string-frame"

p4_find_str_arg --- : FCode
FIND-$ARG ( s -- u true | false ) pfe/dstrings-ext.c

Leave true and its index u in the top string frame if the ANS Forth string matches an element of the frame, else leave false. The index of the top frame element is zero. "find-string-arg"

p4_th_str_arg --- : FCode
TH-$ARG ( u -- $: arg$ ) pfe/dstrings-ext.c

Leave the u-th string in the topmost string frame, where the index u of the top element is zero. Throw an error if the frame stack is empty or if the top frame contains less than u+1 strings. "th-string-arg"

p4_do_drop_str_frame --- : FCode
(DROP-$FRAME) ( -- ) pfe/dstrings-ext.c

Cleanup code for the end of a definition that uses $ARGS{. ;-semicolon should be overloaded to compile it automatically if dynamic string arguments were in use. "paren-drop-string-frame-paren"

p4_str_pop --- : FCode
$POP ( $: a$ -- s: a$) pfe/dstrings-ext.c

Abort if the string stack would underflow when popped.

Otherwise pop the top of the string stack and push it onto the data stack.

If the string is in the current string space and initially bound to the top of the string stack, mark it as garbage by setting its back link to NULL and set the garbage flag.

This word violates the rule that only ANS Forth strings should appear on the data stack, and so is under the hood. "string-pop"

p4_str_push_ext --- : FCode
$PUSH-EXT ( a$ -- $: a$ ) pfe/dstrings-ext.c

Pop an external mstring address from the data stack and push it onto the string stack after checking for room, invoking garbage collection if necessary. Not to be used with a dynamic string because a garbage collection can invalidate its address.

This word violates the normal rule that only ANS Forth strings should appear on the data stack, and so is under the hood. "string-push-ext"

p4_str_breakp_fetch --- : FCode
$BREAKP@ ( -- $stack.break.addr ) pfe/dstrings-ext.c

"string-break-p-fetch"

p4_str_bufp_fetch --- : FCode
$BUFP@ ( -- $buffer.addr ) pfe/dstrings-ext.c

"string-buf-p-fetch"

p4_str_fbreakp_fetch --- : FCode
$FBREAKP@ ( -- frame.stack.break.addr ) pfe/dstrings-ext.c

"string-f-break-p-fetch"

p4_str_fsp0_fetch --- : FCode
$FSP0@ ( -- initial.frame.stack.top.addr ) pfe/dstrings-ext.c

"string-f-s-p-zero-fetch"

p4_str_fsp_fetch --- : FCode
$FSP@ ( -- frame.stack.top.addr ) pfe/dstrings-ext.c

"string-f-s-p-fetch"

p4_str_sp0_fetch --- : FCode
$SP0@ ( -- initial.string.stack.top.addr ) pfe/dstrings-ext.c

"string-s-p-zero-fetch"

p4_str_sp_fetch --- : FCode
$SP@ ( -- string.stack.top.addr ) pfe/dstrings-ext.c

"string-s-p-fetch"

p4_slash_str_frame_item --- : FCode
/$SFRAME-ITEM ( -- frame.stack.item.size ) pfe/dstrings-ext.c

"slash-string-frame-item"

p4_slash_str_frame_stack --- : FCode
/$SFRAME-STACK ( -- max.frame.stack.size ) pfe/dstrings-ext.c

"slash-string-frame-stack"

p4_slash_str_space_header --- : FCode
/$SPACE-HEADER ( -- $space.header.size ) pfe/dstrings-ext.c

"slash-string-space-header"

p4_zero_str_space --- : FCode
0$SPACE ( $space.addr -- ) pfe/dstrings-ext.c

Clear the string buffer, string stack, and string frame stack in the string space starting at space.addr. Any string variables holding strings in the string buffer are left pointing into limbo. This may be executed with the string space in an invalid state, as long as the /$BUF and MAX-#$FRAMES fields of its string space structure are intact. "zero-string-space"

NOTE: This word does not zero fill the string buffer.

p4_cat_str_p_fetch --- : FCode
CAT$P@ ( -- cat$.msa | 0 ) pfe/dstrings-ext.c

"cat-string-fetch"

p4_in_str_buffer_Q --- : FCode
IN-$BUFFER? ( msa -- flag ) pfe/dstrings-ext.c

Leave true if the mstring is in the string buffer. "in-string-buffer-question"

p4_edit_block --- : FCode
EDIT-BLOCK ( blk -- ) pfe/edit-ext.c

start the internal block-editor on the assigned block

p4_edit_text --- : FCode
EDIT-TEXT name ( -- ) pfe/edit-ext.c

start an external EDITOR with the specified filename

p4_edit_error --- : FCode
EDIT-ERROR ( -- ) pfe/edit-ext.c

if an error occured, this routine can be called to invoke an appropriate EDITOR (see also EDIT-BLOCK)

p4_Exec(p4_threadP th) : _export int
  pfe/engine-set.c

init and execute the previously allocated forth-maschine, e.g. pthread_create(&thread_id,0,p4_Exec,threadP);

The following words have been extracted from a big boot init procedure previously existing in PFE. In the boot_system we do initialize all inputs/outputs and load the wordset extensions and the boot-preinit-block or boot-preinit-script. After that, we run script_files to init the application code, and finally the application is started - and if no APPLICATION was set then we do the fallback to the forth interactive INTERPRET loop. The latter is the usual case, use BYE to exit that inifinite loop.

When the mainloop returns, we run the cleanup-routines. They are registered seperatly so they can be run asynchronously - if the application has broken down or it blocks hard on some hardware then we can still run cleanup code in a new forthish context.

p4_call_stop --- : FCode_XE
... pfe/engine-sub.c
p4_call_loop(p4xt xt) : _export void
 ... pfe/engine-sub.c
p4_call(p4xt xt) : _export void
 ... pfe/engine-sub.c
p4_normal_execute(p4xt xt) : _export void
 ... pfe/engine-sub.c
p4_simple_execute(p4xt xt) : _export void
 ... pfe/engine-sub.c
p4_interpret --- : FCode
... pfe/engine-sub.c
p4_include_file(p4_File *fid) : _export void
 ... pfe/engine-sub.c
p4_included1(const p4_char_t *name, int len, int throws) : _export int
 ... pfe/engine-sub.c
p4_included(const p4_char_t* name, int len) : _export void
 ... pfe/engine-sub.c
p4_closeall_files --- : FCode
... pfe/engine-sub.c
p4_ok --- : FCode
... pfe/engine-sub.c
p4_interpret_loop(P4_VOID) : _export int
  pfe/engine-sub.c

the outer interpreter, in PFE the jumppoint for both ABORT and QUIT

p4_cold_system --- : FCode
... pfe/engine-sub.c
p4_boot_system --- : FCode
... pfe/engine-sub.c
p4_include_required --- : FCode
REQUIRED ( ... str-ptr str-len -- ??? ) pfe/environ-ext.c

the filename argument is loaded via INCLUDED as an extension package to the current system. The filename is registered in the current ENVIRONMENT so that it is only INCLUDED once (!!) if called multiple times via REQUIRED or REQUIRES

p4_include_require --- : FCode
REQUIRE ( ... "file-name" -- ... ) pfe/environ-ext.c

parses the next WORD and passes it to REQUIRED this is the self-parsing version of REQUIRED and it does parrallel INCLUDE w.r.t. INCLUDED

p4_environment --- : FCode
ENVIRONMENT ( -- ) pfe/environ-ext.c

execute the VOCABULARY runtime for the ENVIRONMENT-WORDLIST

  : ENVIRONMENT  ENVIRONMENT-WORDLIST CONTEXT ! ;
  ' ENVIRONMENT  ALIAS [ENV] IMMEDIATE

see newstyle ENVIRONMENT?

p4_environment_Q(const p4_char_t* str, p4cell l) : _export p4_char_t*
  ENVIRONMENT? ( a1 n1 -- false | ?? true ) pfe/environ-ext.c

check the environment for a property, usually a condition like questioning the existance of specified wordset, but it can also return some implementation properties like "WORDLISTS" (the length of the search-order) or "#LOCALS" (the maximum number of locals)

Here it implements the environment queries as a SEARCH-WORDLIST in a user-visible vocabulary called ENVIRONMENT

  : ENVIRONMENT?
    ['] ENVIRONMENT >WORDLIST SEARCH-WORDLIST
    IF  EXECUTE TRUE ELSE  FALSE THEN ;
 

special extension: a search for CORE will also find a definition of CORE-EXT or CORE-EXT-EXT or CORE-EXT-EXT-EXT - it just has to be below the ansi-standard maximum length of 31 chars.

if a name like "dstrings-ext" is given, and no such entry can be found, then envQ will try to trigger a (LOADM) of that module, in the hope that this implicit-load does in fact define the answer. Use with care, it's a very new feature.

p4_needs_environment --- : FCode
NEEDS ( name -- ) pfe/environ-ext.c

A self-parsing variant of an environment-query check. It is similar to a simulation like

 
  : NEEDS PARSE-WORD 2DUP ENVIRONMENT? 
    IF DROP ( extra value ) 2DROP ( success - be silent )
    ELSE TYPE ." not available " CR THEN ;
 

however that would only match those worset-envqueries which return a single extra item under the uppermost TRUE flag in the success case. Instead it works more like

 
  : NEEDS PARSE-WORD 2DUP ENVIRONMENT-WORDLIST SEARCH-WORDLIST
    IF 2DROP ( success - be silent and just drop the parsed word )
    ELSE TYPE ." not available " CR THEN ;
 

however we add the same extension as in ENVIRONMENT? as that it can automatically load a wordset module to fullfil a query that looks like "[wordsetname]-ext". Therefore, the following two lines are pretty much identical:

 
  LOADM floating
  NEEDS floating-ext
 

the difference between the two: if somebody did provide a forth level implementation of floating-ext then that implementation might have registered a hint "floating-ext" in the environment-wordlist. This extra-hint will inhibit loading of the binary module even if it exists and not been loaded so far. The LOADM however will not check the ENVIRONMENT-WORDLIST and only check its loadlist of binary wordset modules in the system.

It is therefore recommended to use NEEDS instead of LOADM unless you know you want the binary module, quickly and uncondtionally.

p4_catch --- : FCode
CATCH ( catch-xt* -- 0 | throw#! ) [ANS] pfe/exception-ext.c

execute the given execution-token and catch any exception that can be caught therein. software can arbitrarily raise an exception using THROW - the value 0 means there was no exception, other denote implementation dependent exception-codes.

p4_throw --- : FCode
THROW ( throw#! -- [THROW] | throw# -- ) [ANS] pfe/exception-ext.c

raise an exception - it will adjust the depth of all stacks and start interpreting at the point of the latest CATCH
if n is null nothing happens, the -1 (ie. FALSE ) is the raise-code of ABORT - the other codes are implementation dependent and will result in something quite like ABORT

p4_abort --- : FCode
ABORT ( -- [THROW] ) [ANS] pfe/exception-ext.c

throw - cleanup some things and go back to the QUIT routine

  : ABORT -1 THROW ;
  
p4_abort_quote_execution --- : FCode_XE
((ABORT")) ( -- ) [HIDDEN] pfe/exception-ext.c

compiled by ABORT" what"

p4_abort_quote --- : FCode
'ABORT"' ( [string<">] -- [THROW] ) [ANS] pfe/exception-ext.c

throw like ABORT but print an additional error-message to stdout telling what has happened.

p4_exception_string --- : FCode
(EXCEPTION-STRING: ( exception# [description] -- ) pfe/exception-ext.c

append a node with the given id and a pointer to an extern zstring to the NEXT-EXCEPTION chain-list.

p4_longjmp_loop(int arg) : _export void
 ... pfe/exception-sub.c
p4_throws(int id, const p4_char_t* description, int len) : _export void
 ... pfe/exception-sub.c
p4_at_x_y --- : FCode
AT-XY ( col# row# -- ) [ANS] pfe/facility-ext.c

move the cursor position to the given row and column of the screen. If the output device is not a terminal this will have no effect but can still send an escape sequence.

p4_key_question --- : FCode
KEY? ( -- key-flag ) [ANS] pfe/facility-ext.c

if a character is available from the keyboard, return true. The KEY word will retrieve the actual character.

p4_ekey --- : FCode
EKEY ( -- key-code# ) [ANS] pfe/facility-ext.c

return a keyboard event, the encoding may differ, esp. that it can contain special keys.

p4_ekey_to_char --- : FCode
EKEY>CHAR ( key-code# -- key-code# 0 | char# true! ) [ANS] pfe/facility-ext.c
p4_ekey_question --- : FCode
EKEY? ( -- ekey-flag ) [ANS] pfe/facility-ext.c

check if a character is available from the keyboard to be received - unlike KEY? it will not discard non-visible codes.

p4_emit_question --- : FCode
EMIT? ( -- emit-flag ) [ANS] pfe/facility-ext.c

if EMIT can safely output characters without blocking the forth by waiting for an indefinite time.

p4_ms --- : FCode
MS ( milliseconds# -- ) [ANS] pfe/facility-ext.c

wait at least the specified milliseconds (suspend the forth tasklet)

p4_time_and_date --- : FCode
TIME&DATE ( -- sec# min# hrs# day# month# year# ) [ANS] pfe/facility-ext.c

return the broken down current time

p4_dot_clrscr --- : extern FCode
PAGE ( -- ) [ANS] pfe/facility-ext.c

CLRSCR

p4_ignore_line --- : FCode
#! ( "..." -- ) pfe/facility-mix.c

ignores the rest of the line, defining `#!' is used to support forth scripts executed by the unix kernel

p4_clock_fetch --- : FCode
CLOCK@ ( --- clock-ticks# ) [EXT] pfe/facility-mix.c

return clock(2) - the number of clocks of this proces. To get the number of seconds, divide by CLOCKS_PER_SEC a.k.a. CLK_TCK as represented in the ENVIROMENT for a hosted forth system.

Remember that the process clock will wrap around at some point, therefore only use difference values between two clock reads.

p4_bin --- : FCode
BIN ( access-mode# -- access-mode#' ) [ANS] pfe/file-ext.c

modify the give file access-mode to be a binary-mode

p4_delete_file --- : FCode
DELETE-FILE ( name-ptr name-len -- name-errno# ) [ANS] pfe/file-ext.c

delete the named file and return a status code

p4_file_position --- : FCode
FILE-POSITION ( some-file* -- p,pos# some-errno# ) [ANS] pfe/file-ext.c

return the current position in the file and return a status code. A code of zero means success.

p4_file_size --- : FCode
FILE-SIZE ( some-file* -- s,size# some-errno# ) [ANS] pfe/file-ext.c

return the current size of the file and return a status code. A code of zero means success.

p4_write_line --- : FCode
WRITE-LINE ( buf-ptr buf-len some-file* -- some-errno# ) [ANS] pfe/file-ext.c

write characters from the string buffer to a file, and add the line-terminator to the end of it. returns a status code.

p4_file_status --- : FCode
FILE-STATUS ( file-ptr file-len -- file-subcode# file-errno# ) [ANS] pfe/file-ext.c

check the named file - if it exists the status errno code is zero. The status subcode is implementation-specific and usually matches the file access permission bits of the filesystem.

p4_flush_file --- : FCode
FLUSH-FILE ( some-file* -- some-errno# ) [ANS] pfe/file-ext.c

flush all unsaved buffers of the file to disk. A status code of zero means success.

p4_rename_file --- : FCode
RENAME-FILE ( oldname-ptr oldname-len newname-ptr newname-len -- newname-errno# ) [ANS] pfe/file-ext.c

rename the file named by "oldname" to the name of "newname" returns a status-code where zero means success.

p4_include --- : FCode
INCLUDE ( "filename" -- ??? ) [FTH] pfe/file-mix.c

load the specified file, see also LOAD" filename"

p4_copy_file --- : FCode
COPY-FILE ( src-ptr src-len dst-ptr dst-len -- copy-errno# ) [FTH] pfe/file-mix.c

like RENAME-FILE, copies the file from src-name to dst-name and returns an error-code or null

p4_move_file --- : FCode
MOVE-FILE ( src-ptr src-len dst-ptr dst-len -- move-errno# ) [FTH] pfe/file-mix.c

like RENAME-FILE, but also across-volumes
moves the file from src-name to dst-name and returns an error-code or null

p4_file_rw --- : FCode
FILE-R/W ( buffer* use-block# flag? some-file* -- ) [FTH] pfe/file-mix.c

like FIG-Forth R/W

p4_file_block --- : FCode
FILE-BLOCK ( use-block# some-file* -- buffer* ) [FTH] pfe/file-mix.c
p4_file_buffer --- : FCode
FILE-BUFFER ( use-block# some-file* -- buffer* ) [FTH] pfe/file-mix.c
p4_file_empty_buffers --- : FCode
FILE-EMPTY-BUFFERS ( some-file* -- ) [FTH] pfe/file-mix.c
p4_file_flush --- : FCode
FILE-FLUSH ( some-file* -- ) [FTH] pfe/file-mix.c
 
  simulate      : FILE-FLUSH DUP FILE-SAVE-BUFFERS FILE-EMTPY-BUFFERS ;
  
p4_file_list --- : FCode
FILE-LIST ( use-block# some-file* -- ) [FTH] pfe/file-mix.c
p4_file_load --- : FCode
FILE-LOAD ( use-block# some-file* -- ) [FTH] pfe/file-mix.c
p4_file_save_buffers --- : FCode
FILE-SAVE-BUFFERS ( some-file* -- ) [FTH] pfe/file-mix.c
p4_file_thru --- : FCode
FILE-THRU ( lo-block# hi-block# some-file* -- ) [FTH] pfe/file-mix.c

see THRU

p4_file_update --- : FCode
FILE-UPDATE ( some-file* -- ) [FTH] pfe/file-mix.c
p4_dfaligned(p4cell n) : _export p4cell
 ... pfe/floating-ext.c
p4_to_float(const p4_char_t *p, p4cell n, double *r) : _export int
 ... pfe/floating-ext.c
p4_f_to_d --- : FCode
( f: a -- n,n ) pfe/floating-ext.c

b is the integer representation of a

we use truncation towards zero. compare with F>S and its "FROUND>S" / "FTRUNC>S"

p4_f_p_fetch --- : FCode
FP@ ( -- addr ) pfe/floating-mix.c

returns the floating point stack pointer

p4_f_p_store --- : FCode
FP! ( addr -- ) pfe/floating-mix.c

sets the floating point stack pointer - this is the inverse of FP@

p4_f_equal --- : FCode
F? ( f: a b -- s: a==b ) pfe/floating-mix.c
p4_f_not_equal --- : FCode
F<> ( f: a b -- s: a!=b ) pfe/floating-mix.c
p4_s_to_f --- : FCode
S>F ( n -- f: x ) pfe/floating-mix.c

it's inverse is F>S - convert a cell parameter to floating-point.

p4_f_trunc_to_s --- : FCode
FTRUNC>S (f: x -- s: n ) pfe/floating-mix.c

The word F>S was sometimes defined with a different behavior than FTRUNC>S which is the type-cast behaviour of C according to C99 section 6.3.1.4 - truncation would also match the ANS-Forth specification for F>D.

Some systems used F>S defined to FROUND>S instead. The pfe provides explicit words for both conversions, the word FROUND>S and FTRUNC>S which return single-cell parameters for a floating point number with the conversion method of FTRUNC or FROUND.

In PFE, F>S is a synonym pointing to FTRUNC>S in analogy of the behavior of F>D where no explicit word exists. The inverse of F>S is the cast conversion of S>F.

p4_f_round_to_s --- : FCode
FROUND>S (f: x -- s: n) pfe/floating-mix.c

complements FTRUNC>S for applications that expect F>S to be defined with a rounding behavior like

  : FROUND>S FROUND FTRUNC>S ;
  
p4_f_trunc --- : FCode
FTRUNC (f: x -- x' ) pfe/floating-mix.c

truncate towards zero, discard a fractional part. See also FTRUNC>S conversion and the FROUND and FLOOR adaptors.

  : FTRUNC FDUP F0< IF FCEIL ELSE FLOOR THEN ;

(When available, uses a single call to C99 trunc() internally)

p4_minus_f_rot --- : FCode
-FROT (f: x1 x2 x3 -- x3 x1 x2 ) pfe/floating-mix.c

F-stack equivalent of -ROT

note, some systems call this work F-ROT, here it is the inverse of FROT

p4_f_nip --- : FCode
FNIP (f: x1 x2 -- x2 ) pfe/floating-mix.c

F-stack equivalent of NIP

p4_f_tuck --- : FCode
FTUCK (f: x1 x2 -- x2 x1 x2 ) pfe/floating-mix.c

F-stack equivalent of TUCK

p4_one_over_f --- : FCode
1/F (f: x -- 1/x ) pfe/floating-mix.c
p4_f_square --- : FCode
F^2 (f: x -- x^2 ) pfe/floating-mix.c
p4_f_power_n --- : FCode
F^N ( u f: x -- x^u ) pfe/floating-mix.c

For large exponents, use F** instead. Of course u=-1 is large.

p4_f_two_slash --- : FCode
F2/ (f: x -- x/2 ) pfe/floating-mix.c
p4_f_two_star --- : FCode
F2* (f: x -- x*2 ) pfe/floating-mix.c
p4_f_zero_greater --- : FCode
F0> (f: x -- s: flag ) pfe/floating-mix.c
p4_f_zero_not_equal --- : FCode
F0<> (f: x -- s: flag ) pfe/floating-mix.c
p4_two_plus --- : FCode
2+ ( a# -- a#' | a* -- a*' | a -- a' [??] ) [FTH] pfe/forth-83-ext.c

add 2 to the value on stack (and leave the result there)

  simulate:
    : 2+ 2 + ;
  
p4_two_minus --- : FCode
2- ( a# -- a#' | a* -- a*' | a -- a' [??] ) [FTH] pfe/forth-83-ext.c

substract 2 from the value on stack (and leave the result there)

  simulate:
    : 2- 2 - ;
  
p4_compile --- : FCode
COMPILE ( "word" -- ) [FTH] pfe/forth-83-ext.c

compile the next word. The next word should not be immediate, in which case you would have to use [COMPILE]. For this reason, you should use the word POSTPONE, which takes care it.

  simulate:
    : COMPILE  R> DUP @ , CELL+ >R ;  ( not immediate !!! )
  
p4_vocabulary_RT --- : FCode_RT
((VOCABULARY)) ( -- ) [HIDDEN] pfe/forth-83-ext.c

runtime of a VOCABULARY

p4_vocabulary --- : FCode
VOCABULARY ( "name" -- ) [FTH] pfe/forth-83-ext.c

create a vocabulary of that name. If the named vocabulary is called later, it will run ((VOCABULARY)) , thereby putting it into the current search order. Special pfe-extensions are accessible via CASE-SENSITIVE-VOC and SEARCH-ALSO-VOC

  simulate:
    : VOCABULARY  CREATE ALLOT-WORDLIST
         DOES> ( the ((VOCABULARY)) runtime )
           CONTEXT ! 
    ; IMMEDIATE
  
p4_next_block --- : FCode
--> ( -- ) [FTH] pfe/forth-83-ext.c

does increase BLK and refills the input-buffer from there. Does hence break interpretation of the current BLK and starts with the next. Old-style forth mechanism. You should use INCLUDE

  : --> ?LOADING REFILL ;
  
p4_k --- : FCode
K ( -- k# ) [FTH] pfe/forth-83-ext.c

the 3rd loop index just like I and J

p4_octal --- : FCode
OCTAL ( -- ) [FTH] pfe/forth-83-ext.c

sets BASE to 8. Compare with HEX and DECIMAL

  simulate:
    : OCTAL  8 BASE ! ;
  
p4_s_p_fetch --- : FCode
SP@ ( -- sp-cell* ) [FTH] pfe/forth-83-ext.c

the address of the top of stack. Does save it onto the stack. You could do

    : DUP  SP@ @ ;
  
p4_store_bits --- : FCode
!BITS ( x-bits# x-addr mask# -- ) [FTH] pfe/forth-83-ext.c

at the cell pointed to by addr, change only the bits that are enabled in mask

  simulate:
    : !BITS  >R 2DUP @ R NOT AND SWAP R> AND OR SWAP ! DROP ;
  
p4_power --- : FCode
** ( a# b# -- power-a# ) [FTH] pfe/forth-83-ext.c

raise second to top power

p4_byte_swap --- : FCode
>< ( a -- a' ) [FTH] [OLD] pfe/forth-83-ext.c

byte-swap a word

depracated: use NTOHS which does the same as this word when the local byte-order seems to have no match, and be otherwise a no-op. Note that only the two lower bytes of the top-of-cell are swapped.

p4_byte_swap_move --- : FCode
>MOVE< ( from-addr* to-addr* count# -- ) [FTH] [OLD] pfe/forth-83-ext.c

see MOVE , does byte-swap for each word underway.

depracated: this word has not been very useful lately. It does still stem from times of 16bit forth systems that wanted to interchange data blocks. It is better to use functionality based on NTOHS or NTOHL. Note that this word >MOVE< does swap each 2byte. It is not useful for byte-swapping WCHAR strings as the count is given in bytes, not wchar items.

p4_fetch_bits --- : FCode
@BITS ( x-addr mask# -- x-value# ) [FTH] pfe/forth-83-ext.c

see the companion word => !BITS

  simulate:
    : @BITS  SWAP @ AND ;
  
p4_seal --- : FCode
SEAL ( -- ) [FTH] pfe/forth-83-ext.c

looks through the search-order and kills the ONLY wordset - hence you can't access the primary vocabularies from there.

p4_c_plus_store --- : FCode
C+! ( n addr -- ) pfe/forth-usual-ext.c

Add the low-order byte of _n_ to the byte at _addr_, removing both from the stack.

p4_to_wordlist --- : FCode
">WORDLIST" ( xt -- wordl* ) pfe/forth-usual-ext.c

convert a VOCABULARY-xt into its wordlist reference (as in win32forth)

p4_bounds --- : FCode
BOUNDS ( str len -- str+len str ) pfe/forth-usual-ext.c

Convert _str len_ to range for DO-loop.

  : BOUNDS  ( str len -- str+len str )  OVER + SWAP ;
  
p4_off_store --- : FCode
OFF ( addr -- ) pfe/forth-usual-ext.c

Store 0 at _addr_. Defined in f84 as OFF. See antonym ON!.

   : OFF  ( addr -- )  0 SWAP ! ;
  
p4_on_store --- : FCode
ON! ( addr -- ) pfe/forth-usual-ext.c

Store -1 at _addr_. Defined in f83 as ON. See antonym OFF!.

   : ON!  ( addr -- )  -1 SWAP ! ;
  
p4_append --- : FCode
+PLACE ( str len add2 -- ) pfe/forth-usual-ext.c

Append string _str len_ to the counted string at _addr_. a.k.a. APPEND (being a SYNONYM now)

  : +PLACE   2DUP 2>R  COUNT +  SWAP MOVE ( ) 2R> C+! ;
  
p4_append_char --- : FCode
C+PLACE ( char addr -- ) pfe/forth-usual-ext.c

Append _char_ to the counted string at _addr_. a.k.a. APPEND-CHAR (being a SYNONYM now)

  : C+PLACE   DUP >R  COUNT  DUP 1+ R> C!  +  C! ;
  
p4_place --- : FCode
PLACE ( str len addr -- ) pfe/forth-usual-ext.c

Place the string _str len_ at _addr_, formatting it as a counted string.

  : PLACE  2DUP 2>R  1+ SWAP  MOVE  2R> C! ;
  : PLACE  2DUP C!   1+ SWAP CMOVE ;
  
p4_question_leave --- : FCode
?LEAVE ( cond -- ) pfe/forth-usual-ext.c

leave a (innermost) loop if condition is true

p4_noop --- : extern FCode
NOOP ( -- ) pfe/forth-usual-ext.c

do nothing, used as a place-holder where an execution word is needed

p4_r_p_fetch --- : FCode
RP@ ( -- addr ) pfe/forth-usual-ext.c

returns the return stack pointer

  example:
    : R@ RP@ @ ;
  
p4_r_p_store --- : FCode
RP! ( addr -- ) pfe/forth-usual-ext.c

sets the return stack pointer, reverse of RP@

p4_s_p_store --- : FCode
SP! ( ... addr -- ) pfe/forth-usual-ext.c

sets the stack pointer, reverse of SP@

p4_dash_rot --- : FCode
-ROT ( a b c -- c a b ) pfe/forth-usual-ext.c

inverse of ROT

p4_c_set --- : FCode
CSET ( n addr -- ) pfe/forth-usual-ext.c

set bits in byte at given address

  simulate:
    : CSET  TUCK @ SWAP OR SWAP ! ;
  
p4_c_reset --- : FCode
CRESET ( n addr -- ) pfe/forth-usual-ext.c

reset bits in byte at given address

  simulate:
    : CRESET  TUCK @ SWAP NOT AND SWAP ! ;
  
p4_c_toggle --- : FCode
CTOGGLE ( n addr -- ) pfe/forth-usual-ext.c

toggle bits in byte at given address

  simulate:
    : CTOGGLE  TUCK @ SWAP XOR SWAP ! ;
  
p4_toggle --- : FCode
TOGGLE ( c-addr charmask -- ) pfe/forth-usual-ext.c

toggle the bits given in charmask, see also SMUDGE and = UNSMUDGE

  example: the fig-style SMUDGE had been defined such
    : FIG-SMUDGE LATEST >FFA (SMUDGE#) TOGGLE ;
  
p4_three_dup --- : FCode
3DUP ( x y z -- x y z x y z ) pfe/forth-usual-ext.c

Copy top three elements on the stack onto top of stack.

  : 3DUP   THIRD THIRD THIRD ;

or

  : 3DUP  3 PICK 3 PICK 3 PICK ;
  
p4_three_drop --- : FCode
3DROP ( x y z -- ) pfe/forth-usual-ext.c

Drop the top three elements from the stack.

  : 3DROP   DROP 2DROP ;
  
p4_four_dup --- : FCode
4DUP ( a b c d -- a b c d a b c d ) pfe/forth-usual-ext.c
 
  simulate:
   : 4DUP  4 PICK 4 PICK 4 PICK 4 PICK ;
  
p4_four_drop --- : FCode
4DROP ( x y z -- ) pfe/forth-usual-ext.c

Drop the top three elements from the stack.

  : 4DROP   2DROP 2DROP ;
  
p4_toupper --- : FCode
TOUPPER ( c1 -- c2 ) pfe/forth-usual-ext.c

convert a single character to upper case

    : TOUPPER  >R _toupper ;
  
p4_ascii --- : FCode
ASCII ( [word] -- val ) pfe/forth-usual-ext.c

state smart version of CHAR or [CHAR] resp.

  simulate:
    : ASCII  [COMPILE] [CHAR] 
             STATE @ IF [COMPILE] LITERAL THEN ;
  
p4_control --- : FCode
CONTROL ( [word] -- val ) pfe/forth-usual-ext.c

see ASCII, but returns char - '@'

  simulate:
    : CONTROL  [COMPILE] [CHAR]  [CHAR] @ -  
               STATE @ IF [COMPILE] LITERAL THEN ;
  
p4_vocs --- : FCode
VOCS ( -- ) pfe/forth-usual-ext.c

list all vocabularies in the system

  simulate:
    : VOCS VOC-LINK @ BEGIN DUP WHILE
                            DUP ->WORDLIST.NAME @ ID.
                            ->WORDLIST.LINK @
                      REPEAT DROP ; 
  
p4_fetch_execute --- : FCode
@EXECUTE ( xt -- ? ) pfe/forth-usual-ext.c

same as @ EXECUTE , but checks for null as xt and silently ignores it. Same as in most forths where defined.

  simulate:
    : @EXECUTE  @ ?DUP IF EXECUTE THEN ;
  
p4_file_check --- : FCode
FILE-CHECK ( n -- ) pfe/forth-usual-ext.c

Check for file access error.

  \ : FILE-CHECK    ( n -- )  THROW ;
  : FILE-CHECK      ( n -- )  ABORT" File Access Error " ;
  
p4_memory_check --- : FCode
MEMORY-CHECK ( n -- ) pfe/forth-usual-ext.c

Check for memory allocation error.

  \ : MEMORY-CHECK  ( n -- )  THROW ;
  : MEMORY-CHECK    ( n -- )  ABORT" Memory Allocation Error " ;
  
p4_plus_plus --- : FCode
++ ( addr -- ) pfe/forth-usual-ext.c

Increment the value at _addr_.

  : ++  ( addr -- )  1 SWAP +! ;
  
p4_fetch_plus_plus --- : FCode
@++ ( addr -- addr' x ) pfe/forth-usual-ext.c

Fetch the value _x_ from _addr_, and increment the address by one cell.

  : @++  ( addr -- addr' x )  DUP CELL+ SWAP  @ ;
  
p4_store_plus_plus --- : FCode
!++ ( addr x -- addr' ) pfe/forth-usual-ext.c

Store the value _x_ into _addr_, and increment the address by one cell.

  : !++  ( addr x -- addr' )  OVER !  CELL+ ;
  
p4_nofp_dfaligned(p4cell n) : _export p4cell
 ... pfe/fpnostack-ext.c
p4_nofp_to_float(const p4_char_t *p, p4cell n, double *r) : _export int
 ... pfe/fpnostack-ext.c
p4_nofp_s_to_f --- : FCode
S>F ( n -- x ) pfe/fpnostack-ext.c
p4_nofp_f_trunc_to_s --- : FCode
FTRUNC>S ( x -- n ) pfe/fpnostack-ext.c
p4_nofp_f_round_to_s --- : FCode
FROUND>S ( x -- n ) pfe/fpnostack-ext.c
p4_nofp_f_trunc --- : FCode
FTRUNC ( x -- x' ) pfe/fpnostack-ext.c
p4_nofp_minus_f_rot --- : FCode
-FROT ( x1 x2 x3 -- x3 x1 x2 ) pfe/fpnostack-ext.c
p4_nofp_f_nip --- : FCode
FNIP ( x1 x2 -- x2 ) pfe/fpnostack-ext.c
p4_nofp_f_tuck --- : FCode
FTUCK ( x1 x2 -- x2 x1 x2 ) pfe/fpnostack-ext.c
p4_nofp_one_over_f --- : FCode
1/F ( x -- 1/x ) pfe/fpnostack-ext.c
p4_nofp_f_square --- : FCode
F^2 ( x -- x^2 ) pfe/fpnostack-ext.c
p4_nofp_f_power_n --- : FCode
F^N ( x u -- x^u ) pfe/fpnostack-ext.c

For large exponents, use F** instead. Of course u=-1 is large.

p4_nofp_f_two_slash --- : FCode
F2/ ( x -- x/2 ) pfe/fpnostack-ext.c
p4_nofp_f_two_star --- : FCode
F2* ( x -- x*2 ) pfe/fpnostack-ext.c
p4_nofp_f_zero_greater --- : FCode
F0> ( x -- flag ) pfe/fpnostack-ext.c
p4_nofp_f_zero_not_equal --- : FCode
F0<> ( x -- flag ) pfe/fpnostack-ext.c
p4_gforth_open_dir --- : FCode
open-dir ( c_addr u -- wdirid wior ) gforth open_dir pfe/gforth-ext.c

will vanish without warning. see gforth documentation.

p4_gforth_read_dir --- : FCode
read-dir ( c_addr u1 wdirid -- u2 flag wior ) gforth read_dir pfe/gforth-ext.c

will vanish without warning. see gforth documentation.

p4_gforth_close_dir --- : FCode
close-dir ( wdirid -- wior ) gforth close_dir pfe/gforth-ext.c

will vanish without warning. see gforth documentation.

p4_gforth_linked --- : FCode
linked ( list -- ) \ gforth pfe/gforth-ext.c
 
  : linked        here over @ a, swap ! ;

(note: win32forth calls it "link," )

p4_gforth_chained --- : FCode
chained ( xt list -- ) \ gforth pfe/gforth-ext.c

generic chains

  : chained  linked , ;
  
p4_gforth_chainperform --- : FCode
chainperform ( list -- ) \ gforth pfe/gforth-ext.c

  : chainperform  BEGIN @ dup WHILE dup cell+ perform REPEAT drop ;
  
p4_to_name --- : FCode
>NAME ( cfa -- nfa ) pfe/header-ext.c

converts a pointer to the code-field (CFA) to point then to the corresponding name-field (NFA)

  implementation-specific simulation:
    : >NAME  >LINK L>NAME ;
  
p4_to_link --- : FCode
>LINK ( cfa -- lfa ) pfe/header-ext.c

converts a pointer to the code-field (CFA) to point then to the corresponding link-field (LFA) - in some configurations this can be a very slow operation since the system might need to walk through all header-words in the system, looking for a >NAME that has the cfa and *then* returning the "N>LINK" result here - which might be none at all if the word is a :NONAME. Use always >NAME and treat this word as non-portable just like any assumption about the contents of the >LINK-field. Only in fig-mode and for traditional fig-mode programs, this word may possibly have enough extra assertions to be somewhat reliable. (and fig-mode did not know about SYNONYMs - see note at LINK>).

p4_body_from --- : FCode
BODY> ( pfa -- cfa ) pfe/header-ext.c

trying to convert a pointer to the parameter-field (PFA) to point then to the corresponding code-field (CFA) - note that this is not necessarily the inverse of >BODY instead it is a fast implementation assuming a VARIABLE thing had been used. Every use of "BODY>" is warned in the logfile.

  implementation-specific simulation:
    : BODY> CELL - ;

p4_name_from --- : FCode
NAME> ( nfa -- cfa ) pfe/header-ext.c

converts a pointer to the name-field (NFA) to point then to the corresponding code-field (CFA)

In all cases but a SYNONYM the pfe will behave not unlike the original fig-forth did - being identical to N>LINK LINK> .

p4_link_from --- : FCode
LINK> ( lfa -- cfa ) pfe/header-ext.c

converts a pointer to the link-field (LFA) to point then to the corresponding code-field (CFA)

BEWARE: this one does not care about SYNONYMs and it is the only way to get at the data of a SYNONYM. Therefore, if you have a synonym called A for an old word B then there is a different result using "NAME>" on an A-nfa or using "N>LINK LINK>" since the first "NAME>" will return the xt of B while the latter will return the xt of A - but executing an xt of A is an error and it will THROW

this difference is intentional to allow knowledgable persons to do weird things looking around in the dictionary. The forth standard words will not give you much of a chance to get hold of the nfa of a SYNONYM word anyway - asking FIND for a word A will return the execution token of B immediatly and "NAME>" on that one lead to the nfa of B and not that of A.

p4_l_to_name --- : FCode
L>NAME ( lfa -- nfa ) pfe/header-ext.c

converts a pointer to the link-field (LFA) to point then to the corresponding name-field (CFA) - this one is one of the slowest operation available. One should always use the inverse operation N>LINK and cache an older value if that is needed. Some words might be linked but they do not have a name-field (just the other fields) but this word can not detect that and will try to look into the bits of the dictionary anway in the assumption that there is something - and if done in the wrong place it might even segfault. Only in fig-mode and for traditional fig-mode programs, this word may possibly have enough extra assertions to be somewhat reliable. (and fig-mode did not know about SYNONYMs - see note at LINK>).

 
  implementation-specific configure-dependent fig-only simulation:
  : L>NAME BEGIN DUP C@ 128 AND 0= WHILE 1- REPEAT ;
  
p4_n_to_link --- : FCode
N>LINK ( nfa -- lfa ) pfe/header-ext.c

converts a pointer to the name-field (NFA) to point then to the corresponding link-field (LFA) - this operation is quicker than the inverse L>NAME. This word is a specific implementation detail and should not be used by normal users - instead use always NAME> which is much more portable. Many systems may possibly not even have a >LINK-field in the sense that a @ on this adress will lead to another >NAME. Any operation on the resulting >LINK-adress is even dependent on the current configuration of PFE - only in fig-mode you are asserted to have the classic detail. (and fig-mode did not know about SYNONYMs - see note at LINK>).

 
  implementation-specific configure-dependent fig-only simulation:
    : N>LINK  C@ + ;
  
p4_to_ffa --- : FCode
>FFA ( nfa -- ffa ) obsolete pfe/header-ext.c

converts a pointer to the name-field (NFA) to point then to the corresponding flag-field (FFA) - in traditinal Forth this is the same address. pfe _can_ do different.

  implementation-specific configure-dependent simulation:
    : FFA  1- ;
  
p4_ffa_from --- : FCode
FFA> ( ffa -- nfa ) obsolete pfe/header-ext.c

converts a pointer to the flag-field (FFA) to point then to the corresponding name-field (NFA) - in traditinal Forth this is the same address. pfe _can_ do different.

  implementation-specific configure-dependent simulation:
    : FFA  1+ ;
  
p4_name_to_string --- : FCode
NAME>STRING ( name-token -- str-ptr str-len ) pfe/header-ext.c

convert a name-token into a string-span, used to detect the name for a word and print it. The word ID. can be defined as

  : ID. NAME>STRING TYPE ;

the implementation of NAME>STRING depends on the header layout that is defined during the configuration of the forth system.

  : NAME>STRING COUNT 31 AND ; ( for fig-like names )
  : NAME>STRING COUNT ;        ( default, name is a simple counted string )
  : NAME>STRING @ ZCOUNT ;     ( name-token is a pointer to a C-level string )
  : NAME>STRING COUNT 31 AND   ( hybrid of fig-like and zero-terminated )
       DUP 31 = IF DROP 1+ ZCOUNT THEN
  ;
  : NAME>STRING HEAD:: COUNT CODE:: PAD PLACE PAD ; ( different i86 segments )
 
p4_header_comma --- : FCode
HEADER, ( str-ptr str-len -- ) pfe/header-ext.c

CREATE a new header in the dictionary from the given string, without CFA

  usage: : VARIABLE  BL WORD COUNT HEADER, DOVAR , ;
  
p4_str_header --- : FCode
$HEADER ( bstring -- ) pfe/header-ext.c

CREATE a new header in the dictionary from the given string with the variable runtime (see HEADER, and CREATE:)

  usage: : VARIABLE  BL WORD $HEADER ;
  
p4_latest --- : FCode
LATEST ( -- nfa ) pfe/header-ext.c

return the NFA of the lateset definition in the CURRENT vocabulary

p4_smudge --- : FCode
SMUGDE ( -- ) pfe/header-ext.c

the FIG definition toggles the SMUDGE bit, and not all systems have a smudge bit - instead one should use REVEAL or HIDE

  : SMUDGE LAST @ >FFA SMUDGE-MASK TOGGLE ;
  : SMUDGE LAST @ NAME-FLAGS@ SMUDGE-MASK XOR LAST @ NAME-FLAGS! ;
  : HIDE   LAST @ NAME-FLAGS@ SMUDGE-MASK  OR LAST @ NAME-FLAGS! ;
  
p4_hide --- : FCode
HIDE ( -- ) pfe/header-ext.c

the FIG definition toggles the SMUDGE bit, and not all systems have a smudge bit - instead one should use REVEAL or HIDE

  : HIDE LAST @ FLAGS@ SMUDGE-MASK XOR LAST @ FLAGS! ;
  
p4_reveal --- : FCode
REVEAL ( -- ) pfe/header-ext.c

the FIG definition toggles the SMUDGE bit, and not all systems have a smudge bit - instead one should use REVEAL or HIDE

  : REVEAL LAST @ FLAGS@ SMUDGE-MASK INVERT AND LAST @ FLAGS! ;
  : REVEAL LAST @ CHAIN-INTO-CURRENT ;
  
p4_name_flags_fetch --- : FCode
NAME-FLAGS@ ( nfa -- nfa-flags ) pfe/header-ext.c

get the nfa-flags that corresponds to the nfa given. Note that in the fig-style would include the nfa-count in the lower bits. (see NAME-FLAGS!)

p4_name_flags_store --- : FCode
NAME-FLAGS! ( nfa-flags nfa -- ) pfe/header-ext.c

set the nfa-flags of nfa given. Note that in the fig-style the nfa-flags would include the nfa-count in the lower bits - therefore this should only set bits that had been previously retrieved with NAME-FLAGS@

  : IMMEDIATE LAST @ NAME-FLAGS@ IMMEDIATE-MASK OR LAST @ NAME-FLAGS! ;
  
p4_defer_RT --- : FCode
((DEFER)) ( -- ) pfe/header-ext.c

runtime of DEFER words

p4_defer --- : FCode
DEFER ( 'word' -- ) pfe/header-ext.c

create a new word with ((DEFER))-semantics

  simulate:
    : DEFER  CREATE 0, DOES> ( the ((DEFER)) runtime ) 
       @ ?DUP IF EXECUTE THEN ;
    : DEFER  DEFER-RT HEADER 0 , ;

declare as "DEFER deferword"
and set as "['] executionword IS deferword" (in pfe, you can also use TO deferword to set the execution)

p4_is --- : FCode
IS ( xt-value [word] -- ) pfe/header-ext.c

set a DEFER word (in pfe: set the DOES-field - which is the BODY-field in ans-mode and therefore the same as TO / in fig-mode the DOES-field is one cell higher up than for a CREATE: VARIABLE Use IS freely on each DOES-words in both modes).

  : IS ' 
    STATE @ IF LITERAL, POSTPONE >DOES-BODY POSTPONE ! 
    ELSE >DOES-BODY ! THEN 
  ; IMMEDIATE
  
p4_action_of --- : FCode
ACTION-OF ( [word] -- xt-value ) pfe/header-ext.c

get the BEHAVIOR of a DEFER word when executed. If being compiled then the ACTION-OF will be the value of [word] at the time of execution and not that of compilation time (non-constant).

In PFE it does actually pick whatever is stored in the DOES-field of a word and therefore ACTION-OF may applied to all DOES-words.

p4_defer_store --- : FCode
DEFER! ( xt-value xt-defer -- ) pfe/header-ext.c

A Forth200x definition that is not very useful.

p4_defer_fetch --- : FCode
DEFER@ ( xt1 -- xt2 ) pfe/header-ext.c

get the execution token xt2 that would be executed by the DEFER identified by xt1.

This command is used to obtain the execution contents of a deferred word. A typical use would be to retrieve and save the execution behavior of the deferred word, set the deferred word to a new behavior, and then later restore the old behavior.

If the deferred word identified by _xt1_ is associated with some other deferred word, _xt2_ is the execution token of that other deferred word. To retrieve the execution token of the word currently associated with that other deferred word, use the phrase DEFER@ DEFER@ .

Experience: BEHAVIOR was used many years in OpenBoot and OpenFirmware systems.

In PFE it is the inverse of an IS operation and it will never fail if applied to a word with atleast a body. That's just like IS can be applied to almost every DOES> word where DEFER@ will get the value back.

p4_alias --- : FCode
ALIAS ( some-xt* "name" -- ) [EXT] pfe/header-ext.c

create a defer word that is initialized with the given x-token. DO-ALIAS

p4_synonym_RT --- : FCode_RT
((SYNONYM)) pfe/header-ext.c

should not actually be called ever.

p4_obsoleted_RT --- : FCode_RT
((OBSOLETED)) pfe/header-ext.c

should not actually be called ever.

p4_synonym --- : FCode
SYNONYM ( "newname" "oldname" -- ) pfe/header-ext.c

make an name-alias for a word - this is very different from a DEFER since a DEFER will resolve at runtime. Changing the target of a DEFER via IS will result in changing the BEHAVIOR of all words defined earlier and containing the name of the DEFER.

A SYNONYM however does not have any data field (theoretically not even an execution token), instead it gets resolved at compile time. In theory, you can try to FIND the name of the SYNONYM but as soon as you apply NAME> the execution token of the end-point is returned. This has also the effect that using the inverse >NAME operation will result in the name-token of the other name.

 
    SYNONYM CREATE <BUILDS ( like it is in ANS Forth )
    : FOO CREATE DOES> @ ;
    SEE FOO
    : foo <builds
      does> @ ;
    SYNONYM CREATE CREATE:
    : BAR CREATE 10 ALLOT ;
    SEE BAR
    : bar create: 10 allot ;

(only LINK> does not care about SYNONYMs)

p4_obsoleted --- : FCode
"SYNONYM-OBSOLETED ( "newname" "oldname" -- ) pfe/header-ext.c

same as SYNONYM but on the first use an error message will be displayed on both the screen and the sys-log.

p4_deprecated --- : FCode
(DEPRECATED: ( "newname" [message] -- ) pfe/header-ext.c

add a message for the following word "newname" that should be shown once upon using the following word. Use it like

    (DEPRECATED: myword is obsoleted in Forth200X)
    : myword ." hello world" ;
  
p4_check_deprecated --- : FCode
(CHECK-DEPRECATED) ( nfa* -- nfa* ) pfe/header-ext.c

an internal function that will check a word name to have any deprecation attribution - some words have a (one time) message to be shown to the user, while OBSOLETED-SYNONYM will show a message and rebuild itself as a normal SYNONYM. - Note that most deprecations are only shown once and that they are not emitted when having REDEFINED-MSG OFF.

p4_extern_deprecated --- : FCode
EXTERN,-DEPRECATED: ( "newname" zstring* -- ) pfe/header-ext.c

compile a pointer to an extern (loader) z-string to the dictionary and on execution show a deprecation message once. Note: the new name is smudged+immediate, so it you can not FIND it right after compilation.

see also (DEPRECATED: name message) for the real thing

p4_logmessage --- : FCode
EXTERN,-LOGMESSAGE: ( "newname" zstring* -- ) pfe/header-ext.c

compile a pointer to an extern (loader) z-string to the dictionary and on execution show a logging message once. Note: this name is NOT smudged+immediate.

see also (DEPRECATED: name message) for deprecation messages

p4_dictvar_RT --- : FCode_RT
... pfe/header-sub.c
p4_dictget_RT --- : FCode_RT
... pfe/header-sub.c
p4_paren_help --- : FCode
(HELP) ( str-ptr str-len -- ) pfe/help-ext.c

display help for the specified word (not functional yet)

p4_open_terminal_logfile --- : FCode
OPEN-TERMINAL-LOGFILE ( s-buf s-len -- ) pfe/host-k12.c

open terminal logfile named by the string-buffer all further output to the terminal window is also logged into this file. This is especially useful in embedded environments where the terminal connection is often not used or it is directed to a different location that does not easily allow to redirect the forth output to a file for further examination.

p4_close_terminal_logfile --- : FCode
CLOSE-TERMINAL-LOGFILE ( -- ) pfe/host-k12.c

close terminal logfile opened with OPEN-TERMINAL-LOGFILE

p4_terminal_answer_link --- : FCode
TERMINAL-ANSWER-LINK ( -- sap#* ) pfe/host-k12.c

send terminal-output as a data-message to the specified link sap. Unlike TERMINAL-OUTPUT-LINK the data-messages are in line-mode. The flushed characters are buffered until a non-printable character is seen. This is somewhat more useful when treating pfe as a print service and testing machine, but can not provide for interactivity.

  60 TERMINAL-ANSWER-LINK !
  ...
  TERMINAL-ANSWER-LINK OFF
  
p4_terminal_output_link --- : FCode
TERMINAL-OUTPUT-LINK ( -- sap#* ) pfe/host-k12.c

send terminal-output as a data-message to the specified link sap. This can be used in an embedded systems for a terminal session simulation. setting zero-sap will disable sending message-frames (the zero sap is therefore not usable for output-to-link). The startup default is zero.

  60 TERMINAL-OUTPUT-LINK !
  ...
  TERMINAL-OUTPUT-LINK OFF
  
p4_terminal_input_link --- : FCode
TERMINAL-INPUT-LINK ( -- sap#* ) pfe/host-k12.c

let the forth stdin-handling look for data-messages on this link too. These will be interpreted like messages that come from the interactive forth terminal. This can be used in an embedded systems for a terminal session simulation. setting zero-sap will disable interpreting these incoming data-frames as keyboard-strings (so that the zero sap is therefore not usable for an input-link!). The startup default is zero.

  60 TERMINAL-INPUT-LINK !
  ...
  TERMINAL-INPUT-LINK OFF
  
p4_terminal_emulation_state --- : FCode
TERMINAL-EMULATION-STATE ( -- state* ) pfe/host-k12.c

returns the address of the emulations state variable so it can be read and explicitly changed to another value from forth text. This is a very questionable thing to do as the emulation-state is actually an enumerated value, the ESE will just show question-marks setting this variable to something not understood.

p4_paren_local --- : FCode
(LOCAL) ( strptr strcnt -- ) pfe/locals-ext.c

this word is used to create compiling words that can declare LOCALS| - it shall not be used directly to declare a local, the pfe provides LVALUE for that a purpose beyond LOCALS|

p4_locals_bar --- : FCode
LOCALS| ( xN ... x2 x1 [name1 .. nameN <|>] -- ) pfe/locals-ext.c

create local identifiers to be used in the current definition. At runtime, each identifier will be assigned a value from the parameter stack.
The identifiers may be treated as if being a VALUE , it does also implement the ansi TO extensions for locals. Note that the identifiers are only valid inside the currently compiled word, the SEE decompiled word will show them as ... a.s.o.
see also LVALUE

p4_local_value --- : FCode
LVALUE ( value [name] -- ) pfe/locals-ext.c

declares a single local VALUE using (LOCAL) - a sequence of LVALUE declarations can replace a LOCALS| argument, ie. LOCALS| a b c | is the same as LVALUE a LVALUE b LVALUE c . This should also clarify the runtime stack behaviour of LOCALS| where the stack parameters seem to be assigned in reverse order as opposed to their textual identifier declarations.
compare with VALUE and the pfe's convenience word VAR.

  : LVALUE 
    STATE @ IF 
      VALUE 
    ELSE 
      BL WORD COUNT DUP (LOCAL) (TO)
    THEN
  ; IMMEDIATE
  
p4_local_buffer_var --- : FCode
LBUFFER: ( size [name] -- ) pfe/locals-ext.c

declares a single local VALUE using (LOCAL) - which will hold the address of an area like BUFFER: but carved from the return-stack (as in C with alloca). This local buffer will be automatically given up at the end of the word. The return-stack-pointer will be increased only at the time of the p4_local_buffer_var function (and the address assigned to the LVALUE) so that the provided size gets determined at runtime. Note that in some configurations the forth-return-stack area is quite small - for large string operations you should consider to use a POCKET-PAD in pfe.

  : LBUFFER:
    STATE @ IF 
      BUFFER:
    ELSE 
      :NONAME ( size -- rp* ) R> RP@ - DUP RP! SWAP >R ;NONAME
      COMPILE, POSTPONE LVALUE
    THEN
  ; IMMEDIATE
  
p4_emu_sendme_command(k12_emu_type_t* emul_id, const u8_t* str, int len) : status_t
  BEWARE: helper function, make sure to save LEM context and setup the pfe/main-k12.c

forth's REGTH (if it uses a cpu register for that). the p4_emu_sendme_command function will create an eventbuffer that will land in the term-k12 getevent loop - it will work as if the the string has been magically typed on the terminal. It can be used to send a string from LEM-context (during a config-request) to the PFE-context (in its getevent loop). The string will be implicitly terminated with a CR to start execution in the engine's interpret_loop.

p4_allocate --- : FCode
ALLOCATE ( size# -- alloc*! 0 | 0 errno#! ) [ANS] pfe/memory-alloc-ext.c

Allocate a chunk of memory from the system heap. use FREE to release the memory area back to the system.
A code of zero means success.

p4_free --- : FCode
FREE ( alloc* -- errno# ) [ANS] pfe/memory-alloc-ext.c

Free the memory from ALLOCATE A code of zero means success.

p4_resize --- : FCode
RESIZE ( alloc* newsize# -- alloc*' errno# ) [ANS] pfe/memory-alloc-ext.c

Resize the system memory chunk. A code of zero means success. Our implementation returns the old pointer on failure.

p4_dict_allocate(int items, int size, int align, void** lower, void** upper) : _export void*
 ... pfe/memory-sub.c
p4_cold --- : FCode
COLD ( -- ) [FTH] pfe/misc-ext.c

cold abort - reinitialize everything and go to QUIT routine ... this routine is implemented as a warm-boot in pfe.

  : COLD [ ALSO ENVIRONMENT ] EMPTY SCRIPT-FILE INCLUDED QUIT ;
  
p4_u_d_dot_r --- : FCode
UD.R ( x,x# r# -- ) [FTH] pfe/misc-ext.c
p4_u_d_dot --- : FCode
UD. ( x,x# -- ) [FTH] pfe/misc-ext.c

see also UD.R

p4_id_dot --- : FCode
ID. ( some-nfa* -- ) [FTH] pfe/misc-ext.c

print the name-field pointed to by the nfa-argument. a synonym for .NAME - but this word is more portable due its heritage from fig-forth.

in fig-forth the name-field is effectivly a bstring with some flags, so the nfa's count has to be masked out, e.g.

  : .NAME COUNT 32 AND TYPE ;

in other pfe configurations, the name might not contain the flags it it just a counted string - and there may be even more possibilities.

  : .NAME COUNT TYPE ;

you should more and more convert your code to use the sequence NAME>STRING TYPE which is widely regarded as the better variant.

p4_dash_roll --- : FCode
-ROLL ( x...[n-1] y n# -- y x...[n-1] | num# -- ) [FTH] pfe/misc-ext.c

the inverse of ROLL

p4_random --- : FCode
RANDOM ( n# -- random# ) [FTH] pfe/misc-ext.c

returns random number with 0 <= n2 < n1)

  : RANDOM ?DUP IF _random SWAP MOD ELSE _random THEN ;
  
p4_srand --- : FCode
SRAND ( seed# -- ) [FTH] pfe/misc-ext.c
p4_plus_under --- : FCode
+UNDER ( n1 x n2 -- n1+n2 x ) [EXT] pfe/misc-ext.c

quicker than

  : UNDER+  ROT + SWAP ;

Note: the old pfe version of UNDER+ is obsolete as it is in conflict with a comus word of the same name. The behavior of this word will continue to exist under the name of (UNDER+). Users are encouraged to use the comus behavior of UNDER+ which does already exist under the name of +UNDER. In the future pfe will be changed to pick up the comus behavior making UNDER+ and +UNDER to be synonyms. In the current version there will be load-time warning on usages of "UNDER+".

p4_under_plus --- : FCode
"(UNDER+)" ( n1 n2 -- n1+n2 n2 ) [FTH] pfe/misc-ext.c

quicker than

  : (UNDER+) TUCK + SWAP ; or : (UNDER+) DUP UNDER+ ;
  
p4_plus_to_execution --- : FCode_XE
((+TO)) ( val -- ) [HIDDEN] pfe/misc-ext.c

execution compiled by +TO adds the stack-val to the lvalue compiled

p4_plus_to_local_execution --- : FCode_XE
((+TO.local)) ( val -- ) [HIDDEN] pfe/misc-ext.c

same as ((+TO)) when the lvalue is a LOCALS| value
compiled by +TO

p4_plus_to --- : FCode
+TO ( val [name] -- ) [FTH] pfe/misc-ext.c

add the val to the named VALUE or LOCALS| value

p4_build_array --- : FCode
BUILD-ARRAY ( x#...[dim] dim# -- memsize# ) [FTH] pfe/misc-ext.c

writes X, n1, ... nX into the dictionary - returns product n1 * n2 * ... * nX

p4_access_array --- : FCode
ACCESS-ARRAY ( x#...[dim#] array* --- array* value# ) [FTH] pfe/misc-ext.c

see BUILD-ARRAY

p4_source_line --- : FCode
SOURCE-LINE ( -- source-line# ) [FTH] pfe/misc-ext.c

if SOURCE is from EVALUATE (or QUERY ) then the result is 0 else the line-numbers start from 1

p4_source_name --- : FCode
SOURCE-NAME ( -- source-name-ptr source-name-len ) [FTH] pfe/misc-ext.c

if SOURCE is from INCLUDE then the result is the filename, otherwise a generic name for the SOURCE-ID is given.

p4_th_pocket --- : FCode
TH'POCKET ( pocket# -- pocket-ptr pocket-len ) [FTH] pfe/misc-ext.c

returns the specified pocket as a S" string reference

p4_pocket_pad --- : FCode
POCKET-PAD ( -- pocket-ptr ) [FTH] pfe/misc-ext.c

The p4_pocket_pad function Returns the next pocket. A pocket has usually the size of a maxstring, see ENVIRONMENT /STRING (but can be configured to be different, mostly when MAXPATH > /STRING ) Note that a pocket is a temporary and forth internal functions do sometimes call POCKET-PAD too, especially when building filenames and getting a literal (but temporary) string from the keyboard. Functions are not expected to hold references to this transient area any longer than building a name and calling another word with it.

Usage of a pocket pad is a good way to make local temporary buffers superfluous that are only used to construct a temporary string that usually gets swallowed by another function.

  depracated code:
    create temp-buffer 255 allot
    : make-temp ( str buf )
           temp-buffer place  " .tmp" count temp-buffer append
           temp-buffer count make-file ;
  replace with this:
    : make-temp ( str buf )
         pocket-pad >r
         r place  " .tmp" count r append
         r> count make-file
    ;
  
p4_wl_hash --- : FCode
WL-HASH ( buf-ptr buf-len -- buf-hash# ) [FTH] pfe/misc-ext.c

calc hash-code for selection of thread in a threaded-vocabulary

p4_topmost --- : FCode
TOPMOST ( some-wordlist* -- some-topmost-nfa* ) [FTH] pfe/misc-ext.c

that last valid word in the specified vocabulary

p4_ls_words --- : FCode
LS.WORDS ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_ls_primitives --- : FCode
LS.PRIMITIVES ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_ls_cdefs --- : FCode
LS.COLON-DEFS ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_ls_ddefs --- : FCode
LS.DOES-DEFS ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_ls_constants --- : FCode
LS.CONSTANTS ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_ls_variables --- : FCode
LS.VARIABLES ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_ls_vocabularies --- : FCode
LS.VOCABULARIES ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_ls_markers --- : FCode
LS.MARKERS ( -- ) [FTH] pfe/misc-ext.c

see WORDS

p4_w_fetch --- : FCode
W@ ( some-wchar* -- some-wchar# | some* -- some# [?] ) [FTH] pfe/misc-ext.c

fetch a 2byte-val from address

p4_w_store --- : FCode
W! ( value# some-wchar* -- | value# wchar* -- [?] ) [FTH] pfe/misc-ext.c

store a 2byte-val at addressed 2byte-value

p4_w_plus_store --- : FCode
W+! ( value# some-wchar* -- | value# wchar* -- [?] ) [FTH] pfe/misc-ext.c

add a 2byte-val to addressed 2byte-value

p4_backspace --- : FCode
BACKSPACE ( -- ) [FTH] pfe/misc-ext.c

reverse of SPACE

p4_Q_stop --- : FCode
?STOP ( -- stop-flag ) [FTH] pfe/misc-ext.c

check for 'q' pressed - see => ?CR

p4_start_Q_cr --- : FCode
START?CR ( -- ) [FTH] pfe/misc-ext.c

initialized for more-like effect - see => ?CR

p4_Q_cr --- : FCode
?CR ( -- cr-flag ) [FTH] pfe/misc-ext.c

like CR , stop 25 lines past START?CR

p4_close_all_files --- : FCode
CLOSE-ALL-FILES ( -- ) [FTH] pfe/misc-ext.c
p4_dot_memory --- : FCode
.MEMORY ( -- ) [FTH] pfe/misc-ext.c
p4_dot_status --- : FCode
.STATUS ( -- ) [FTH] pfe/misc-ext.c

display internal variables

  : .STATUS .VERSION .CVERSION .MEMORY .SEARCHPATHS .DICTVARS .REGSUSED ;
  
p4_paren_emit --- : FCode
(EMIT) ( char# -- ) [FTH] pfe/misc-ext.c

like EMIT and always to screen - the routine to be put into *EMIT*

p4_paren_expect --- : FCode
(EXPECT) ( a b -- ) [FTH] pfe/misc-ext.c

like EXPECT and always from screen - the routine to be put into *EXPECT*

p4_paren_key --- : FCode
(KEY) ( -- key# ) [FTH] pfe/misc-ext.c

like KEY and always from screen - the routine to be put into *KEY*

p4_paren_type --- : FCode
(TYPE) ( str* len# -- ) [FTH] pfe/misc-ext.c

like TYPE and always to screen - the routine to be put into *TYPE*

p4_standard_io --- : FCode
STANDARD-I/O ( -- ) [FTH] pfe/misc-ext.c

initialize *TYPE* , *EMIT* , *EXPECT* and *KEY* to point directly to the screen I/O routines,
namely (TYPE) , (EMIT) , (EXPECT) , (KEY)

p4_executes_execution --- : FCode_XE
((EXECUTES)) ( fkey# -- ) [HIDDEN] pfe/misc-ext.c

compiled by EXECUTES

p4_executes --- : FCode
EXECUTES ( fkey# [word] -- ) [EXT] pfe/misc-ext.c

stores the execution token of following word into the callback pointer for the specified function-key

p4_help --- : FCode
HELP ( "name" -- ) [FTH] [EXEC] pfe/misc-ext.c

will load the help module in the background and hand over the parsed name to (HELP) to be resolved. If no (HELP) word can be loaded, nothing will happen.

p4_edit_blockfile --- : FCode
EDIT-BLOCKFILE ( "name" -- ) [FTH] [EXEC] pfe/misc-ext.c

will load the edit module in the background and look for a word called EDIT-BLOCK that could be used to edit the blockfile. If no EDIT-BLOCKFILE word can be loaded, nothing will happen. Otherwise, OPEN-BLOCKFILE is called followed by 0 EDIT-BLOCK to start editing the file at the first block.

p4_argc --- : FCode
ARGC ( -- arg-count ) [FTH] pfe/misc-ext.c
p4_argv --- : FCode
ARGV ( arg-n# -- arg-ptr arg-len ) [FTH] pfe/misc-ext.c
p4_expand_fn --- : FCode
EXPAND-FN ( name-ptr name-len buf-ptr -- buf-ptr buf-len ) [FTH] pfe/misc-ext.c
 
  : e.g. s" includefile" POCKET-PAD EXPAND-FN ;
  
p4_load_quote_execution --- : FCode_XE
((LOAD")) ( -- ? ) [HIDDEN] pfe/misc-ext.c
p4_load_quote --- : FCode
LOAD" ( [filename<">] -- ??? ) [FTH] [OLD] pfe/misc-ext.c

load the specified file - this word can be compiled into a word-definition obsolete! use OPEN-BLOCKFILE name LOAD

p4_system --- : FCode
SYSTEM ( command-ptr command-len -- command-exitcode# ) [FTH] pfe/misc-ext.c

run a shell command (note: embedded systems have no shell)

p4_system_quote_execution --- : FCode_XE
((SYSTEM")) ( ... -- exitcode# ) [HIDDEN] pfe/misc-ext.c

compiled by SYSTEM" commandline"

p4_system_quote --- : FCode
SYSTEM" ( [command-line<">] -- command-exitcode# ) [FTH] [OLD] pfe/misc-ext.c

run a shell command (note:embedded systems have no shell) obsolete! use S" string" SYSTEM

p4_create_var --- : FCode
CREATE: ( "name" -- ) [FTH] pfe/misc-ext.c

this creates a name with the VARIABLE runtime. Note that this is the FIG-implemenation of CREATE whereas in ANS-Forth mode we have a CREATE identical to FIG-style

  : CREATE: BL WORD $HEADER DOVAR A, ;
  
p4_buffer_var --- : FCode
BUFFER: ( size# "name" -- ) [FTH] pfe/misc-ext.c

this creates a name with the VARIABLE runtime and ALLOTs memory

  : BUFFER: BL WORD $HEADER DOVAR A, ALLOT ;
  
p4_r_tick_fetch --- : FCode
R'@ ( R: a b -- a R: a b ) [FTH] pfe/misc-ext.c

fetch the next-under value from the returnstack. used to interpret the returnstack to hold two LOCALS| values. ( R@ / 2R@ / R>DROP / R"@)

p4_r_tick_store --- : FCode
R'! ( x R: a b -- R: x b ) [FTH] pfe/misc-ext.c

store the value into the next-under value in the returnstack. used to interpret the returnstack to hold two LOCALS| values. see R'@ for inverse operation

p4_r_quote_fetch --- : FCode
R"@ ( R: a b c -- a R: a b c ) [FTH] pfe/misc-ext.c

fetch the second-under value from the returnstack. used to interpret the returnstack to hold three LOCALS| values. see R"! for inverse operation ( R'@ R@ / 2R@ / R>DROP )

p4_r_quote_store --- : FCode
R"! ( x R: a b c -- R: x b c ) [FTH] pfe/misc-ext.c

store the value into the second-under value in the returnstack. used to interpret the returnstack to hold three LOCALS| values. see R"@ for inverse operation

p4_r_store --- : FCode
R! ( x R: a -- R: x ) [FTH] pfe/misc-ext.c

store the value as the topmost value in the returnstack. see R@ for inverse operation ( R'@ / R"@ / 2R@ / 2R!)

p4_two_r_store --- : FCode
2R! ( x y R: a b -- R: x y ) [FTH] pfe/misc-ext.c

store the value as the topmost value in the returnstack. see 2R@ for inverse operation ( R'@ / R"@ / 2R@ / 2R!)

p4_dup_to_r --- : FCode
DUP>R ( val -- val R: val ) [FTH] pfe/misc-ext.c

shortcut, see R>DROP
note again that the following will fail:

  : DUP>R DUP >R ;
  
p4_r_from_drop --- : FCode
R>DROP ( R: val -- R: ) [FTH] pfe/misc-ext.c

shortcut (e.g. in CSI-Forth)
note that the access to R is configuration dependent - only in a traditional fig-forth each NEST will be one cell wide - in case that there are no LOCALS| of course. And remember, the word above reads like the sequence R> and DROP but that is not quite true.

  : R>DROP R> DROP ; ( is bad - correct might be )  : R>DROP R> R> DROP >R ;
  
p4_two_r_from_drop --- : FCode
2R>2DROP ( R: a b -- R: ) [FTH] pfe/misc-ext.c

this is two times R>DROP but a bit quicker. it is however really quick compared to the sequence 2R> and 2DROP

p4_clearstack --- : FCode
CLEARSTACK ( -- ) [FTH] pfe/misc-ext.c

reset the parameter stack to be empty

  : CLEARSTACK  S0 SP! ;
  
_p4_access(const char *fn, int how) : int
  use as _P4_access, a #define from _missing.h pfe/_missing.c
_p4_rename(const char *source, const char *target) : int
 ... pfe/_missing.c
p4_module --- : FCode
MODULE ( "name" -- old-current ) pfe/module-ext.c

create a new WORDLIST with the given name. It will also have an implicit hidden vocabulary just as well and all DEFINITIONS will go into that hidden wordlist. Therefore the old CURRENT is memorized on the cs-stack.

effectivly, CONTEXT[1] will have the wordlist-id of the public wordlist "name" and CONTEXT[0] will have the hidden wordlist contained in "name" - the hidden wordlist will always be known as HIDDEN' so that it can be re-referenced without need to use ALSO just to access a single definition from just another vocabulary. Note that HIDDEN' is defined immediate (a VOCABULARY' ) to modify the ORDER inside a colon definition.

  : MODULE
    CURRENT @ ( -- old-current )
    VOCABULARY
    ALSO LATEST NAME> EXECUTE ALSO DEFINITIONS
    C" HIDDEN'" $CREATE WORDLIST CONTEXT !
  ;
  
p4_end_module --- : FCode
END-MODULE ( old-current -- ) pfe/module-ext.c

clean up the cs-stack from the last MODULE definition. Effectivly, MODULE definitions can be nested.

  : END-MODULE ( old-current )
    PREVIOUS PREVIOUS CURRENT ! 
  
p4_export --- : FCode
EXPORT ( old-current "name" -- old-current ) pfe/module-ext.c

the named word in the hidden dictionary (i.e. the wordlist referenced in CURRENT) is exported into the public wordlist of it (i.e. which is in this implementation CONTEXT[1]). The actual implemenation will create a DEFER-word in the public wordlist withits parameter area pointing to the cfa of the hidden implementation.

  : EXPORT
    CURRENT @ CONTEXT CELL+ @ CURRENT !
    DEFER CURRENT !
    LATEST COUNT CURRENT @ SEARCH-WORDLIST
    IF LATEST NAME> >BODY ! ELSE ABORT" can't find word to export" THEN
  ;
  
p4_expose_module --- : FCode
EXPOSE-MODULE ( "name" -- ) pfe/module-ext.c

affects the search order, ALSO module-wid CONTEXT ! hidden'

  : EXPOSE-MODULE 
     ALSO S" HIDDEN'" 
     ' DUP VOC? ABORT?" is no vocabulary" >VOC 
     SEARCH-WORDLIST 0= IF " no hidden vocabulary found" THEN
     DUP VOC? ABORT?" hidden is no vocabulary" EXECUTE
  ;
  
p4_also_module --- : FCode
ALSO-MODULE ( "name" -- ) pfe/module-ext.c

affects the search-order, ALSO module-wid CONTEXT !

  : ALSO-MODULE
    ' DUP VOC? ABORT?" is no vocabulary" 
    ALSO EXECUTE
  ;
  
p4_nvram_words --- : FCode
NVRAM,WORDS ( -- ) pfe/option-ext.c

Print a list of WORDS in the NVRAM buffer. Try to show also the current value, atleast for NVRAM numbers and strings. Words can be added or changed with the help of NVRAM,SET or NVRAM,USE

Values in the NVRAM buffer will survive a COLD reboot, in many hosted environments however the NVRAM will be lost on program exit.

p4_nvram_as --- : FCode
NVRAM,AS ( str-ptr str-len "varname" -- ) pfe/option-ext.c

set the NVRAM variable to the specified string.

Some NVRAM strings do not take effect until next COLD reboot.

p4_nvram_to --- : FCode
NVRAM,TO ( number "varname" -- ) pfe/option-ext.c

set the NVRAM variable to the specified number.

Most NVRAM numbers do not take effect until next COLD reboot.

p4_nvram_z_fetch --- : FCode
NVRAM,Z@ ( "varname" -- z-str ) pfe/option-ext.c

Return the string pointer of the NVRAM string item, or null if no such item exists.

p4_nvram_s_fetch --- : FCode
NVRAM,S@ ( "varname" -- str-ptr str-len ) pfe/option-ext.c

Return the string span of the NVRAM string item, or double null if no such item exists.

p4_nvram_Q_fetch --- : FCode
NVRAM,?@ ( number "varname" -- number' ) pfe/option-ext.c

Return the value of the NVRAM value item, or leave the original number untouched (i.e. the default value for your option).

p4_SetOptionsDefault(p4_sessionP set, int len) : _export void
 ... pfe/option-set.c
p4_AddOptions(p4_sessionP set, int argc, const char** argv) : _export int
 ... pfe/option-set.c
p4_SetOptions(p4_sessionP set, int len, int argc, const char** argv) : _export int
 ... pfe/option-set.c
p4_FreeOptions(int returncode, p4_sessionP set) : _export int
  pfe/option-set.c

de-init the session struct

p4_SetOptions , p4_AddOptions

p4_SetModules(p4_sessionP set, p4Words* modules) : _export int
 ... pfe/option-set.c
p4_gettimeofday(p4ucell* sec, p4ucell* usec) : _export void
  pfe/p4-gettimeofday.c

helper function - both arg pointers MUST be given

p4_ntohs --- : FCode
NTOHS ( w -- w' ) pfe/posix-ext.c

if current host-encoding is bigendian, this is a NOOP otherwise byteswap the lower 16-bit bits of the topofstack. see W@ and W! (on some platforms, the upper bits are erased, on others not)

p4_ntohl --- : FCode
NTOHL ( l -- l' ) pfe/posix-ext.c

if current host-encoding is bigendian, this is a NOOP otherwise byteswap the lower 32-bit bits of the topofstack. see L@ and L! (being usually just @ and ! ) (on some platforms, the upper bits are erased, on others not)

p4_definitions --- : FCode
DEFINITIONS ( -- ) pfe/search-order-ext.c

make the current context-vocabulary the definition-vocabulary, that is where new names are declared in. see ORDER

p4_get_current --- : FCode
GET-CURRENT ( -- voc ) pfe/search-order-ext.c

return the current definition vocabulary, see DEFINITIONS

p4_get_order --- : FCode
GET-ORDER ( -- vocn ... voc1 n ) pfe/search-order-ext.c

get the current search order onto the stack, see SET-ORDER

p4_search_wordlist --- : FCode
SEARCH-WORDLIST ( str-ptr str-len voc -- 0 | xt 1 | xt -1 ) pfe/search-order-ext.c

almost like FIND or (FIND) -- but searches only the specified vocabulary.

p4_set_current --- : FCode
SET-CURRENT ( voc -- ) pfe/search-order-ext.c

set the definition-vocabulary. see DEFINITIONS

p4_set_order --- : FCode
SET-ORDER ( vocn ... voc1 n -- ) pfe/search-order-ext.c

set the search-order -- probably saved beforehand using GET-ORDER

p4_wordlist --- : FCode
WORDLIST ( -- voc ) pfe/search-order-ext.c

return a new vocabulary-body for private definitions.

p4_also --- : FCode
ALSO ( -- ) pfe/search-order-ext.c

a DUP on the search ORDER - each named vocabulary replaces the topmost ORDER vocabulary. Using ALSO will make it fixed to the search-order. (but it is not nailed in trap-conditions as if using DEFAULT-ORDER )

  order:   vocn ... voc2 voc1 -- vocn ... voc2 voc1 voc1
  
p4_order --- : FCode
ORDER ( -- ) pfe/search-order-ext.c

show the current search-order, followed by the CURRENT DEFINITIONS vocabulary and the ONLY base vocabulary

p4_previous --- : FCode
PREVIOUS ( -- ) pfe/search-order-ext.c

the invers of ALSO , does a DROP on the search ORDER of vocabularies.

  order: vocn ... voc2 voc1 -- vocn ... voc2 
  example: ALSO PRIVATE-VOC DEFINTIONS (...do some...) PREVIOUS DEFINITIONS
  
p4_default_order --- : FCode
DEFAULT-ORDER ( -- ) pfe/search-order-ext.c

nail the current search ORDER so that it will even survive a trap-condition. This default-order can be explicitly loaded with RESET-ORDER

p4_reset_order --- : FCode
RESET-ORDER ( -- ) pfe/search-order-ext.c

load the DEFAULT-ORDER into the current search ORDER - this is implicitly done when a trap is encountered.

p4_search_init --- : FCode
"ENVIRONMENT WORDLISTS" ( -- value ) pfe/search-order-ext.c

the maximum number of wordlists in the search order

p4_getpid --- : FCode
$PID ( -- pid ) pfe/shell-os-ext.c

calls system's getpid

p4_getuid --- : FCode
$UID ( -- val ) pfe/shell-os-ext.c

calls system's getuid

p4_geteuid --- : FCode
$EUID ( -- val ) pfe/shell-os-ext.c

calls system's geteuid

p4_getgid --- : FCode
$GID ( -- val ) pfe/shell-os-ext.c

calls system's getgid

p4_umask --- : FCode
UMASK ( val -- ret ) pfe/shell-os-ext.c

calls system's umask

p4_home --- : FCode
$HOME ( -- str-ptr str-len ) pfe/shell-os-ext.c

calls system's getenv(HOME)

p4_user --- : FCode
$USER ( -- str-ptr str-len ) pfe/shell-os-ext.c

calls system's getenv(USER)

p4_cwd --- : FCode
$CWD ( -- str-ptr str-len ) pfe/shell-os-ext.c

calls system's getcwd

p4_pwd --- : FCode
PWD ( -- ) pfe/shell-os-ext.c

calls system's getcwd and prints it to the screen

  : PWD  $CWD TYPE ;
  
p4_chdir --- : FCode
CHDIR ( bstring -- ) pfe/shell-os-ext.c

change the current directory.
(under VxWorks it is global! do not use in scripts!!)

p4_install_signal_handlers(void) : _export void
 ... pfe/signals-ext.c
p4_swap_signals(void) : _export void
 ... pfe/signals-ext.c
p4_forth_signal(int sig, p4xt xt) : _export p4xt
 ... pfe/signals-ext.c
p4_load_signals(p4_Wordl *wid) : _export void
 ... pfe/signals-ext.c
p4_raise --- : FCode
(RAISE) ( signal# -- ) [FTH] pfe/signals-ext.c

send a SIGNAL to self OLD: use RAISE-SIGNAL

p4_raise_signal --- : FCode
RAISE-SIGNAL ( signal# -- ior ) [FTH] pfe/signals-ext.c
p4_smart_interpret_char(char c) : p4xt
 ... pfe/smart-go-ext.c
_p4_smart_interpret_init(char c, char const * nm, int l) : p4_char_t*
 ... pfe/smart-go-ext.c
p4_smart_interpret_init(char c, char const * nm, int l) : void
 ... pfe/smart-go-ext.c
p4_smart_interpret_store --- : FCode
SMART-INTERPRET! ( -- ) pfe/smart-go-ext.c

enables/disables the SMART-INTERPRET extension in INTERPRET , (actually stores an XT in DEFER inside the mainloop interpreter)

p4_narrow_changer --- : FCode
"NARROW-CHANGER(" ( changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c
p4_narrow_inputlist --- : FCode
"NARROW-INPUTLIST(" ( changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c
p4_narrow_outputlist --- : FCode
"NARROW-OUTPUTLIST(" ( changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c
p4_narrow_input_variant --- : FCode
"NARROW-INPUT-VARIANT(" ( variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

0 = default, 1 = 'S', 2 = 'R', ... 4 = 'P', ... 7 = 'M', .. 14 = 'F'

p4_narrow_output_variant --- : FCode
"NARROW-OUTPUT-VARIANT(" ( variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c
p4_narrow_input_stack --- : FCode
"NARROW-INPUT-STACK(" ( stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

0 = default, 1 = 'S', 2 = 'R', ... 4 = 'P', ... 7 = 'M', .. 14 = 'F'

p4_narrow_output_stack --- : FCode
"NARROW-OUTPUT-STACK(" ( stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c
p4_narrow_input_argument --- : FCode
"NARROW-INPUT-ARGUMENT(" ( arg# stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

0 = default, 1 = 'S', 2 = 'R', ... 4 = 'P', ... 7 = 'M', .. 14 = 'F' arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_narrow_output_argument --- : FCode
"NARROW-OUTPUT-ARGUMENT(" ( arg# stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_narrow_input_argument_name --- : FCode
"NARROW-INPUT-ARGUMENT-NAME(" ( arg# stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

0 = default, 1 = 'S', 2 = 'R', ... 4 = 'P', ... 7 = 'M', .. 14 = 'F' arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_narrow_output_argument_name --- : FCode
"NARROW-OUTPUT-ARGUMENT-NAME(" ( arg# stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_narrow_input_argument_type --- : FCode
"NARROW-INPUT-ARGUMENT-TYPE(" ( arg# stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

0 = default, 1 = 'S', 2 = 'R', ... 4 = 'P', ... 7 = 'M', .. 14 = 'F' arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_narrow_output_argument_type --- : FCode
"NARROW-OUTPUT-ARGUMENT-TYPE(" ( arg# stk-char which# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_canonic_input_type --- : FCode
"CANONIC-INPUT-TYPE(" ( arg# stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

0 = default, 1 = 'S', 2 = 'R', ... 4 = 'P', ... 7 = 'M', .. 14 = 'F' arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_canonic_output_type --- : FCode
"CANONIC-OUTPUT-TYPE(" ( arg# stk-char variant# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

arg# is [0] = TOS and [1] = UNDER, same as the pick values where 3 2 1 0 2 pick . =:= 2

p4_rewriter_test --- : FCode
"REWRITER-TEST(" ( "tracked-stack -- input-stack" -- ) [EXT] pfe/stackhelp-ext.c

suppose that the left side is a tracked stack line during compiling and the right side is a candidate changer input stack. Test whethr the candidate does match and the complete changer would be allowed to run a rewrite in the track stack buffer.

Possible conditions include: the left side has not enough arguments or... any argument on the right side has a type specialization that does not match as a valid suffix to their counterpart on the left side.

p4_rewriter_input_arg --- : FCode
"REWRITER-INPUT-ARG(" ( arg# "tracked-stack -- changer" -- ) [EXT] pfe/stackhelp-ext.c

suppose that the left side is a tracked stack line during compiling and the right side is a candidate changer input stack. Assume the righthand candidate does match - look at the given argument on the left side and show the prefix being copied to the output trackstack when the rewrite-rule is gettin applied later.

p4_rewrite_line --- : FCode
"REWRITE-LINE(" ( "stack-layout" -- ) [EXT] pfe/stackhelp-ext.c

fill rewrite-buffer with a stack-layout to be processed. see REWRITE-SHOW.

p4_rewrite_show --- : FCode
"REWRITE-SHOW." ( -- ) [EXT] pfe/stackhelp-ext.c

show current rewrite-buffer.

p4_rewrite_stack_test --- : FCode
"REWRITE-STACK-TEST(" ( "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

check whether this stackhelp does match on current rewrite-buffer and say oK/No respectivly.

p4_rewrite_input_arg --- : FCode
"REWRITE-INPUT-ARG(" ( arg# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

check whether this stackhelp does match on current rewrite-buffer and in the given input match show us the argument but only the good prefix i.e. the type constraint being cut off already.

p4_rewrite_stack_result --- : FCode
"REWRITE-STACK-RESULT(" ( "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

rewrite the current rewrite-buffer and show the result that would occur with this stackhelp being applied.

p4_narrow_input_notation --- : FCode
"NARROW-INPUT-NOTATION(" ( notation# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c
p4_narrow_output_notation --- : FCode
"NARROW-OUTPUT-NOTATION(" ( notation# changer# "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c
p4_rewrite_stackdef_test --- : FCode
"REWRITE-STACKDEF-TEST(" ( "stackdef" ) [EXT] pfe/stackhelp-ext.c

match a stackdef (single variant of stacks). assume: single variant in rewrite-buffer and single variant in stackdef-arg and only one changer in arg-stackhelp

p4_rewrite_stackdef_result --- : FCode
"REWRITE-STACKDEF-RESULT(" ( "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

assume: only one changer (if more are provided then only the first is used) only one stackdef variant in inputlist

p4_rewrite_test --- : FCode
"REWRITE-TEST(" ( "stackhelp" -- ) [EXT] pfe/stackhelp-ext.c

Test whether the given changer would match the current line. assume: only one changer (if more are provided then only the first is used)

p4_narrow_inputdef_for_stackdef(pair_t inputlist, pair_t stackdef) : int
  return 1 if "inputlist" was narrowed. pfe/stackhelp-ext.c

return 0 if no good inputdef was found in inputlist variants.

p4_find_stackhelp_body(const p4_char_t* word, p4cell len) : stackhelp_body*
  FIND word in the search-order pfe/stackhelp-ext.c

and find a matching stackhelp entry in the stackhelp-wordlist. We do check for a matching XT to allow for multiple words with the same name. If this find-routine is too specific then try again with a direct search.

p4_stackhelpcomment --- : FCode
"|(" ( [string] -- ) [EXT] pfe/stackhelp-ext.c

add a checkstack notation for the LAST word or just try to match the given notation with the stacklayout traced so far - possibly casting a few types as needed.

p4_stackhelps(void) : void
  implicit PFE.word.ptr / PFE.word.len args pfe/stackhelp-ext.c
p4_stackhelp --- : FCode
STACKHELP ( [name] -- ) [EXT] pfe/stackhelp-ext.c

show the stackhelp info registered for this name.

p4_stackhelp_execute_procs(const char* str, const char* end) : int
  call it after p4_stackhelp_rewrite : it does consume any pfe/stackhelp-ext.c

stackhelp infos that ought to be executed to be a check. This applies also to exitpoints! - no argument as it does work on the CHK.line internal buffer

p4_search_stackhelp(word, len) : ___ p4char* nfa =
  or fallback to first stackhelp available pfe/stackhelp-ext.c
p4_slash_string --- : FCode
/STRING ( str-ptr str-len n -- str-ptr' str-len' ) pfe/string-ext.c

shorten the buffer from the beginning by n characters, i.e.

   str-ptr += n ;
   str-len -= n; 
  
p4_blank --- : FCode
BLANK ( str-ptr str-len -- ) pfe/string-ext.c

FILL a given buffer with BL blanks

p4_cmove --- : FCode
CMOVE ( from-ptr to-ptr len# -- ) pfe/string-ext.c

memcpy an area from->to for len bytes, starting at the lower addresses, see CMOVE>

p4_cmove_up --- : FCode
CMOVE> ( from-ptr to-ptr len# -- ) pfe/string-ext.c

memcpy an area from->to for len bytes, starting with the higher addresses, see CMOVE

p4_compare --- : FCode
COMPARE ( str1-ptr str1-len str2-ptr str2-len -- diff# ) pfe/string-ext.c

compare both str-buffers, return 0 if they are equal, -1 if lower or shorter, and 1 if greater or longer

p4_sliteral --- : FCode
SLITERAL ( C: str-ptr str-len -- S: str-ptr str-len ) pfe/string-ext.c

this word does almost the same as LITERAL - it takes an S" string as specified in the CS-STACK at compile time and compiles into the current definition where it is returned as if there were a direct string-literal. This can be used to compute a string-literal at compile-time and hardwire it.

  example:
    : ORIGINAL-HOME  [ $HOME COUNT ] SLITERAL ; ( -- str-ptr str-len )
  
p4_field --- : FCode
FIELD ( offset size "name" -- offset+size ) pfe/struct-ext.c

create a field - the workhorse for both STRUCT and STRUCTURE implementations. The created fieldname is an OFFSET:-word that memorizes the current offset in its PFA and will add that offset on runtime. This forth-word does *not* align.

  : FIELD CREATE
    OVER ,
    +
  DOES>
     @ +
  ;
  
p4_sizeof_XT --- : FCode_XE
SIZEOF ( "name" -- size ) pfe/struct-ext.c

get the size-value from a previous structure definition

  : SIZEOF   ' >BODY @  STATE @ IF [COMPILE] LITERAL THEN ; IMMEDIATE
  
p4_structure_RT --- : FCode_RT
STRUCTURE ( "name" -- here zero-offset ) exec pfe/struct-ext.c

start a structure definition

  : STRUCTURE: CREATE !CSP
    HERE
    0 DUP ,
  DOES>
    CREATE @ ALLOT
  ;
  
p4_endstructure --- : FCode
ENDSTRUCTURE ( here some-offset -- ) pfe/struct-ext.c

finalize a previously started STRUCTURE definition

  : ENDSTRUCTURE  SWAP !  ?CSP ;
  
p4_struct --- : FCode
STRUCT ( "name" -- here zero-offset ) pfe/struct-ext.c

begin definition of a new structure (mpe.000)

  : STRUCT CREATE  !CSP
    HERE
    0 DUP ,
  DOES>
    @
  ;
  
p4_end_struct --- : FCode
END-STRUCT ( here some-offset -- ) pfe/struct-ext.c

terminate definition of a new structure (mpe.000)

  : END-STRUCT  SWAP !  ?CSP ;
  
p4_subrecord --- : FCode
SUBRECORD ( outer-offset "name" -- outer-offset here zero-offset ) pfe/struct-ext.c

begin definition of a subrecord (mpe.000)

  : STRUCT CREATE  
    HERE
    0 DUP ,
  DOES>
    @
  ;
  
p4_end_subrecord --- : FCode
END-SUBRECORD ( outer-offset here some-offset -- outer-offset+some ) pfe/struct-ext.c

end definition of a subrecord (mpe.000)

  : END-SUBRECORD  TUCK SWAP !  + ;
  
p4_array_of --- : FCode
ARRAY-OF ( some-offset n len "name" -- some-offset ) pfe/struct-ext.c

a FIELD-array

  : ARRAY-OF * FIELD ;
  
p4_variant --- : FCode
VARIANT ( outer-offset "name" -- outer-offset here zero-offset ) pfe/struct-ext.c

Variant records describe an alternative view of the current record or subrecord from the start to the current point. The variant need not be of the same length, but the larger is taken

  : VARIANT SUBRECORD ;
  
p4_end_variant --- : FCode
END-VARIANT ( outer-offset here some-offset -- outer-offset ) pfe/struct-ext.c

terminate definition of a new variant (mpe.000)

  : END-STRUCT  TUCK SWAP !  2DUP < IF NIP ELSE DROP THEN ;
  
p4_instance --- : FCode
INSTANCE ( len "name" -- ) pfe/struct-ext.c

Create a named instance of a named structure.

  : INSTANCE  CREATE ALLOT ;
  
p4_instance_addr --- : FCode
INSTANCE-ADDR ( len -- addr ) pfe/struct-ext.c

Create nameless instance of a structure and return base address.

  : INSTANCE-ADDR  HERE SWAP ALLOT ;
  
p4_backward_mark --- : FCode
pfe/system-ext.c

memorizes the current DP on the CS-STACK used for later. Useful for creation of compiling words, eg. BEGIN , see AHEAD

  simulate:
    : <MARK ?COMP  HERE ;
  
p4_backward_resolve --- : FCode
pfe/system-ext.c

resolves a previous , actually pushes the DP-address memorized at BRANCH or => ?BRANCH in compiling words like UNTIL

  simulate:
    : <RESOLVE ?COMP  , ;
  
p4_forward_mark --- : FCode
MARK> ( -- DP-mark ) compile-only pfe/system-ext.c

makes room for a pointer in the dictionary to be resolved through RESOLVE> and does therefore memorize that cell's address on the CS-STACK Mostly used after BRANCH or => ?BRANCH in compiling words like IF or ELSE

  simulate:
    : MARK> ?COMP  HERE 0 , ;
  
p4_forward_resolve --- : FCode
RESOLVE> ( DP-mark -- ) compile-only pfe/system-ext.c

resolves a pointer created by MARK> Mostly used in compiling words like THEN

  simulate:
    : RESOLVE> ?COMP  HERE SWAP ! ;
  
p4_branch --- : FCode
BRANCH ( -- ) pfe/system-ext.c

compiles a branch-runtime into the dictionary that can be resolved with MARK<d or <RESOLVE. Usage:

      BRANCH MARK&lt;     or
      BRANCH &gt;RESOLVE  or ...

this is the runtime-portion of ELSE - the use of ELSE should be preferred. See also => ?BRANCH

  : BRANCH COMPILE (BRANCH) ;
  
p4_q_branch --- : FCode
?BRANCH ( -- ) pfe/system-ext.c

compiles a cond-branch-runtime into the dictionary that can be resolved with >MARK&d or RESOLVE>. Usage:

      ?BRANCH MARK&lt;     or
      ?BRANCH &gt;RESOLVE  or ...

this is the runtime-portion of IF - the use of IF should be preferred. See also BRANCH

  : ?BRANCH COMPILE (?BRANCH) ;
  
p4_termcatch --- : FCode
TERMCATCH ( str-ptr str-len some-xt* -- str-ptr str-len' catch-code# ) pfe/termcatch-ext.c

create a catch-domain around the token to be executed. This works the same as CATCH. Additionally all terminal output of that word is being captured to the buffer being provided as an argument. The maximum length input argument is modified flagging the actual length of captured output stream as the output argument. Note that in most cases a POCKET-PAD is just not big enough, atleast many error condition notifications tend to be quite lengthy for byte counted forth strings.

  : TERMCATCH TERM-CAPTURE-ON CATCH >R TERM-CAPTURE-OFF R> ;
  
p4_show_control_strings --- : FCode
SHOW-TERM-CONTROLS ( -- ) for debugging pfe/term-ext.c

show the current mappings for the terminal output may give hints about what is wrong if the output seems to miss some functionality

p4_show_rawkey_strings --- : FCode
SHOW-TERM-ESC-KEYS ( -- ) for debugging pfe/term-ext.c

show the current mappings for the terminal input may give hints about what is wrong if the input seems to miss some functionality

p4_show_termcap --- : FCode
SHOW-TERMCAP ( -- ) for debugging pfe/term-ext.c

print the termcap strings used for input and output may give hints about what is wrong if the terminal seems to miss some functionality

p4_assume_vt100 --- : FCode
ASSUME_VT100 ( -- ) pfe/term-ext.c

load hardwired VT100-termcap into the terminal-driver

p4_assume_dumbterm --- : FCode
ASSUME_DUMBTERM ( -- ) pfe/term-ext.c

load hardwired DUMBTERM-termcap into the terminal-driver

p4_gotoxy --- : FCode
GOTOXY ( x y -- ) pfe/term-ext.c

move the cursor to the specified position on the screen - this is usually done by sending a corresponding esc-sequence to the terminal.

p4_question_xy --- : FCode
?XY ( -- x y ) pfe/term-ext.c

returns the cursor position on screen, on a real unix system this includes a special call to the screen driver, in remote systems this can be the expected position as seen on the client side's terminal driver.

p4_ekey_to_fkey --- : FCode
EKEY>FKEY ( key-code# -- key-code# 0 | fkey-code# true! ) pfe/term-ext.c

If the input ekey value was not an extended key then flag is set to FALSE and the value is left unchanged. Compare to EKEY>CHAR for the inverse.

If the input eky was an extended key then the value will be modified such that shifted values are transposed to their base EKEY plus K-SHIFT-MASK - therefore the K-SHIFT-MASK is only apropriate for the result fkey-code values of the p4_ekey_to_fkey function.

p4_defined --- : extern FCode
[DEFINED] ( "name" -- flag ) pfe/toolbelt-ext.c

Search the dictionary for _name_. If _name_ is found, return TRUE; otherwise return FALSE. Immediate for use in definitions.

[DEFINED] word ( -- nfa|0 ) immediate does check for the word using find (so it does not throw like ' ) and puts it on stack. As it is immediate it does work in compile-mode too, so it places its argument in the cs-stack then. This is most useful with a directly following [IF] clause, so that sth. like an [IFDEF] word can be simulated through [DEFINED] word [IF]

 
  : [DEFINED] BL WORD FIND NIP ; IMMEDIATE
  
p4_undefined --- : extern FCode
[UNDEFINED] ( "name" -- flag ) pfe/toolbelt-ext.c

Search the dictionary for _name_. If _name_ is found, return FALSE; otherwise return TRUE. Immediate for use in definitions.

see [DEFINED]

p4_empty --- : FCode
EMPTY ( -- ) pfe/toolbelt-ext.c

Reset the dictionary to a predefined golden state, discarding all definitions and releasing all allocated data space beyond that state.

p4_third --- : FCode
THIRD ( x y z -- x y z x ) pfe/toolbelt-ext.c

Copy third element on the stack onto top of stack.

  : THIRD   2 PICK ;
  
p4_fourth --- : FCode
FOURTH ( w x y z -- w x y z w ) pfe/toolbelt-ext.c

Copy fourth element on the stack onto top of stack.

  : FOURTH  3 PICK ;
  
p4_two_nip --- : FCode
2NIP ( w x y z -- y z ) pfe/toolbelt-ext.c

Drop the third and fourth elements from the stack.

  : 2NIP   2SWAP 2DROP ;
  
p4_andif --- : FCode
ANDIF ( p ... -- flag ) pfe/toolbelt-ext.c

Given `p ANDIF q THEN`, _q_ will not be performed if _p_ is false.

  : ANDIF  S" DUP IF DROP " EVALUATE ; IMMEDIATE
  
p4_orif --- : FCode
ORIF ( p ... -- flag ) pfe/toolbelt-ext.c

Given `p ORIF q THEN`, _q_ will not be performed if _p_ is true.

  : ORIF   S" DUP 0= IF DROP " EVALUATE ; IMMEDIATE
  
p4_scan --- : FCode
SCAN ( str len char -- str+i len-i ) pfe/toolbelt-ext.c

Look for a particular character in the specified string.

  : SCAN     
     >R  BEGIN  DUP WHILE  OVER C@ R@ -
         WHILE  1 /STRING  REPEAT THEN
     R> DROP ;

ie. scan for first occurence of c in string

    : SCAN >R BEGIN DUP OVER C@ R@ = 0= OR WHILE 
                     1- SWAP 1- SWAP REPEAT R> DROP ;
  
p4_skip --- : FCode
SKIP ( str len char -- str+i len-i ) pfe/toolbelt-ext.c

Advance past leading characters in the specified string.

  : SKIP     
    >R  BEGIN  DUP WHILE  OVER C@ R@ =
         WHILE  1 /STRING  REPEAT THEN
     R> DROP ;

ie. skip leading characters c

    : SKIP  >R BEGIN DUP OVER C@ R@ = OR WHILE 
                     1- SWAP 1- SWAP REPEAT R> DROP ;
  
p4_back --- : FCode
BACK ( str len char -- str len-i ) pfe/toolbelt-ext.c

Look for a particular character in the string from the back toward the front.

  : BACK     
     >R  BEGIN  DUP WHILE
         1-  2DUP + C@  R@ =
     UNTIL 1+ THEN
     R> DROP ;
  
p4_div_split --- : FCode
/SPLIT ( a m a+i m-i -- a+i m-i a i ) pfe/toolbelt-ext.c

Split a character string _a m_ at place given by _a+i m-i_. Called "cut-split" because "slash-split" is a tongue twister.

  : /SPLIT  DUP >R  2SWAP  R> - ;
  
p4_is_white --- : FCode
IS-WHITE ( char -- flag ) pfe/toolbelt-ext.c

Test char for white space.

  : IS-WHITE   33 - 0< ;
  
p4_trim --- : FCode
TRIM ( str len -- str len-i ) pfe/toolbelt-ext.c

Trim white space from end of string.

  : TRIM    
     BEGIN  DUP WHILE
         1-  2DUP + C@ IS-WHITE NOT
     UNTIL 1+ THEN ;
  
p4_bl_scan --- : FCode
BL-SCAN ( str len -- str+i len-i ) pfe/toolbelt-ext.c

Look for white space from start of string

  : BL-SCAN 
     BEGIN  DUP WHILE  OVER C@ IS-WHITE NOT
     WHILE  1 /STRING  REPEAT THEN ;
  
p4_bl_skip --- : FCode
BL-SKIP ( str len -- str+i len-i ) pfe/toolbelt-ext.c

Skip over white space at start of string.

  : BL-SKIP 
     BEGIN  DUP WHILE  OVER C@ IS-WHITE
     WHILE  1 /STRING  REPEAT THEN ;
 
  
p4_starts_Q --- : FCode
STARTS? ( str len pattern len2 -- str len flag ) pfe/toolbelt-ext.c

Check start of string.

  : STARTS?   DUP >R  2OVER  R> MIN  COMPARE 0= ;
  
p4_ends_Q --- : FCode
ENDS? ( str len pattern len2 -- str len flag ) pfe/toolbelt-ext.c

Check end of string.

  : ENDS?   DUP >R  2OVER  DUP R> - /STRING  COMPARE 0= ;
  
p4_is_digit --- : FCode
IS-DIGIT ( char -- flag ) pfe/toolbelt-ext.c

Test _char_ for digit [0-9].

  : IS-DIGIT   [CHAR] 0 -  10 U< ;
  
p4_is_alpha --- : FCode
IS-ALPHA ( char -- flag ) pfe/toolbelt-ext.c

Test _char_ for alphabetic [A-Za-z].

  : IS-ALPHA  32 OR  [CHAR] a -  26 U< ;
  
p4_is_alnum --- : FCode
IS-ALNUM ( char -- flag ) pfe/toolbelt-ext.c

Test _char_ for alphanumeric [A-Za-z0-9].

  : IS-ALNUM  
     DUP IS-ALPHA  ORIF  DUP IS-DIGIT  THEN  NIP ;
  
p4_split_next_line --- : FCode
SPLIT-NEXT-LINE ( src . -- src' . str len ) pfe/toolbelt-ext.c

Split the next line from the string.

  : SPLIT-NEXT-LINE 
     2DUP #EOL-CHAR SCAN  
     DUP >R  1 /STRING  2SWAP R> - ;

FIXME: inform Neil Bawd that this is probably not what he wanted. replace /STRING with /SPLIT here.

p4_view_next_line --- : FCode
VIEW-NEXT-LINE ( src . str len -- src . str len str2 len2 ) pfe/toolbelt-ext.c

Copy next line above current line.

  : VIEW-NEXT-LINE 
     2OVER 2DUP #EOL-CHAR SCAN NIP - ;
  
p4_next_word --- : FCode
NEXT-WORD ( -- str len ) pfe/toolbelt-ext.c

Get the next word across line breaks as a character string. _len_ will be 0 at end of file.

  : NEXT-WORD         
     BEGIN   BL WORD COUNT      ( str len )
         DUP IF EXIT THEN
         REFILL
     WHILE  2DROP ( ) REPEAT ;  
  
p4_lexeme --- : FCode
LEXEME ( "name" -- str len ) pfe/toolbelt-ext.c

Get the next word on the line as a character string. If it's a single character, use it as the delimiter to get a phrase.

  : LEXEME             
     BL WORD ( addr) DUP C@ 1 =
         IF  CHAR+ C@ WORD  THEN
     COUNT ;
  
p4_h_sh --- : FCode
H# ( "hexnumber" -- n ) pfe/toolbelt-ext.c

Get the next word in the input stream as a hex single-number literal. (Adopted from Open Firmware.)

  : H#  ( "hexnumber" -- n )  \  Simplified for easy porting.
     0 0 BL WORD COUNT                  
     BASE @ >R  HEX  >NUMBER  R> BASE !
         ABORT" Not Hex " 2DROP          ( n)
     STATE @ IF  POSTPONE LITERAL  THEN
     ; IMMEDIATE
  
p4_backslash_backslash --- : FCode
\\ ( "..." -- ) pfe/toolbelt-ext.c

Ignore the rest of the input stream.

  : \\   BEGIN  -1 PARSE  2DROP  REFILL 0= UNTIL ;
  
p4_tick_th --- : FCode
'th ( n "addr" -- &addr[n] ) pfe/toolbelt-ext.c

Address `n CELLS addr +`.

  : 'th     ( n "addr" -- &addr[n] )
     S" 2 LSHIFT " EVALUATE
     BL WORD COUNT EVALUATE
     S" + " EVALUATE
     ; IMMEDIATE
  
p4_paren_dot --- : FCode
(.) ( n -- addr u ) pfe/toolbelt-ext.c

Convert _n_ to characters, without punctuation, as for `.` (dot), returning the address and length of the resulting string.

  : (.)  ( n -- addr u )  DUP ABS 0 <# #S ROT SIGN #> ;
  
p4_cell_minus --- : FCode
CELL- ( addr -- addr' ) pfe/toolbelt-ext.c

Decrement address by one cell

  : CELL-  ( addr -- addr' )  CELL - ;
  
p4_hiword --- : FCode
HIWORD ( xxyy -- xx ) pfe/toolbelt-ext.c

The high half of the value.

  : HIWORD  ( xxyy -- xx )  16 RSHIFT ;
  
p4_loword --- : FCode
LOWORD ( xxyy -- yy ) pfe/toolbelt-ext.c

The low half of the value.

  : LOWORD  ( xxyy -- yy )  65535 AND ;
  
p4_rewind_file --- : FCode
REWIND-FILE ( file-id -- ior ) pfe/toolbelt-ext.c

Rewind the file.

  : REWIND-FILE       ( file-id -- ior )
     0 0 ROT REPOSITION-FILE ;
  
p4_dot_s --- : FCode
.S ( -- ) pfe/tools-ext.c

print the stack content in vertical nice format. tries to show cell-stack and float-stack side-by-side,

Depending on configuration, there are two parameter stacks: for integers and for floating point operations. If both stacks are empty, .S will display the message <stacks empty>.

If only the floating point stack is empty, .S displays the integer stack items in one column, one item per line, both in hex and in decimal like this (the first item is topmost):

  12345 HEX 67890 .S
     	424080 [00067890]
          12345 [00003039] ok

If both stacks ar not empty, => .S displays both stacks, in two columns, one item per line

  HEX 123456.78E90 ok
  DECIMAL 123456.78E90 .S
     	   291 [00000123]          1.234568E+95
     1164414608 [45678E90] ok

Confusing example? Remember that floating point input only works when the BASE number is DECIMAL. The first number looks like a floating point but it is a goodhex double integer too - the number base is HEX. Thus it is accepted as a hex number. Second try with a decimal base will input the floating point number.

If only the integer stack is empty, => .S shows two columns, but he first columns is called <stack empty>, and the second column is the floating point stack, topmost item first.

p4_question --- : FCode
? ( addr -- ) pfe/tools-ext.c

Display the (integer) content of at address addr. This word is sensitive to BASE

  simulate:
    : ?  @ . ;
  
p4_dump --- : FCode
DUMP ( addr len -- ) pfe/tools-ext.c

show a hex-dump of the given area, if it's more than a screenful it will ask using => ?CR

You can easily cause a segmentation fault of something like that by accessing memory that does not belong to the pfe-process.

p4_see --- : FCode
SEE ( "word" -- ) pfe/tools-ext.c

decompile word - tries to show it in re-compilable form.

(SEE) tries to display the word as a reasonable indented source text. If you defined your own control structures or use extended control-flow patterns, the indentation may be suboptimal.

  simulate:
    : SEE  [COMPILE] ' (SEE) ; 
  
p4_words --- : FCode
WORDS ( -- ) pfe/tools-ext.c

uses CONTEXT and lists the words defined in that vocabulary. usually the vocabulary to list is named directly in before.

  example:
     FORTH WORDS  or  LOADED WORDS
  
p4_new_ahead --- : FCode
AHEAD ( -- DP-mark ORIG-magic ) compile-only pfe/tools-ext.c
 
  simulate:
    : AHEAD  BRANCH MARK> (ORIG#) ;
  
p4_bye --- : FCode
BYE ( -- ) no-return pfe/tools-ext.c

should quit the forth environment completly

p4_cs_pick --- : FCode
CS-PICK ( 2a 2b 2c ... n -- 2a 2b 2c ... 2a ) pfe/tools-ext.c

pick a value in the compilation-stack - note that the compilation stack _can_ be seperate in some forth-implemenations. In PFE the parameter-stack is used in a double-cell fashion, so CS-PICK would 2PICK a DP-mark and a COMP-magic, see PICK

p4_cs_roll --- : FCode
CS-ROLL ( 2a 2b 2c ... n -- 2b 2c ... 2a ) pfe/tools-ext.c

roll a value in the compilation-stack - note that the compilation stack _can_ be seperate in some forth-implemenations. In PFE the parameter-stack is used in a double-cell fashion, so CS-ROLL would 2ROLL a DP-mark and a COMP-magic, see ROLL

p4_bracket_else --- : FCode
[ELSE] ( -- ) pfe/tools-ext.c

eat up everything upto and including the next [THEN]. count nested [IF] ... [THEN] constructs. see [IF]

  this word provides a simple pre-compiler mechanism
  
p4_bracket_if --- : FCode
[IF] ( flag -- ) pfe/tools-ext.c

check the condition in the CS-STACK. If true let the following text flow into INTERPRET , otherwise eat up everything upto and including the next [ELSE] or [THEN] . In case of skipping, count nested [IF] ... [THEN] constructs.

  this word provides a simple pre-compiler mechanism
  
p4_assembler --- : FCode
ASSEMBLER ( -- ) pfe/tools-ext.c

set the ASSEMBLER-WORDLIST as current CONTEXT

p4_create_code --- : FCode
CODE ( "name" -- ) pfe/tools-ext.c

CREATE a new name and put PFA adress into the CFA place.

NOTE: this description (PFA into CFA) is only correct for traditional indirect threaded code (ITC). The other variants use a block info in the CFA - there we will start a normal colon word which is cut off immediately by a ;CODE directive to enter the machine-level.

BE AWARE: The TOOLS-EXT will not provide an END-CODE or any other word in the ASSEMBLER wordlist which is required to start any useful assembler programming. After requiring ASSEMBLER-EXT you will see a second "CODE" in the EXTENSIONS wordlist that will also provide an optimized execution than the result of this standard-forth implemenation.

p4_semicolon_code_execution --- : FCode_XE
;CODE ( -- ) pfe/tools-ext.c

Does end the latest word (being usually some DOES> part) and enters machine-level (in EXEC-mode).

BE AWARE: The TOOLS-EXT will not provide an END-CODE or any other word in the ASSEMBLER wordlist which is required to start any useful assembler programming. After requiring ASSEMBLER-EXT you will see a second ";CODE" in the EXTENSIONS wordlist that will also provide an optimized execution than the result of this standard-forth implemenation.

The Standard-Forth implementation will actually compile a derivate of BRANCH into the dictionary followed by ;. The compiled word will not jump to the target adress (following the execution token) but it will call the target adress via the host C stack. The target machine level word (C domain) will just return here for being returned (Forth domain). Hence END-CODE may be a simple RET, comma!

p4_end_code --- : FCode
END-CODE ( "name" -- ) pfe/tools-ext.c

call PREVIOUS and add PROC LEAVE assembler snippet as needed for the architecture - usually includes bits to "return from subroutine". Remember that not all architectures are support and PFE usually does only do variants of call-threading with a separate loop for the inner interpreter that does "call into subroutine".

Some forth implementations do "jump into routine" and the PROC LEAVE part would do "jump to next routine" also known as next-threading. The sbr-call-threading is usually similar to the native subroutine-coding of the host operating system. See CODE

On some machine types, this word is NOT DEFINED!

p4_vlist --- : FCode
VLIST ( -- ) pfe/tools-mix.c

The VLIST command had been present in FIG and other forth implementations. It has to list all accessible words. In PFE it list all words in the search order. Well, the point is, that we do really just look into the search order and are then calling WORDS on that Wordl. That way you can see all accessible words in the order they might be found. Uses => ?CR

p4_store_csp --- : FCode
!CSP ( -- ) pfe/tools-mix.c

put SP into CSP
used in control-words

p4_Q_csp --- : FCode
?CSP ( -- ) pfe/tools-mix.c

check that SP == CSP otherwise THROW
used in control-words

p4_Q_comp --- : FCode
?COMP ( -- ) pfe/tools-mix.c

check that the current STATE is compiling otherwise THROW
often used in control-words

p4_Q_exec --- : FCode
?EXEC ( -- ) pfe/tools-mix.c

check that the current STATE is executing otherwise THROW
often used in control-words

p4_Q_file --- : FCode
?FILE ( file-id -- ) pfe/tools-mix.c

check the file-id otherwise (fixme)

p4_Q_loading --- : FCode
?LOADING ( -- ) pfe/tools-mix.c

check that the currently interpreted text is from a file/block, otherwise THROW

p4_Q_pairs --- : FCode
?PAIRS ( a b -- ) pfe/tools-mix.c

if compiling, check that the two magics on the CS-STACK are identical, otherwise throw
used in control-words

p4_Q_stack --- : FCode
?STACK ( -- ) pfe/tools-mix.c

check all stacks for underflow and overflow conditions, and if such an error condition is detected THROW

p4_paren_forget --- : FCode
(FORGET) ( addr -- ) pfe/tools-mix.c

forget everything above addr - used by FORGET

p4_paren_dictlimit --- : FCode
(DICTLIMIT) ( -- constvalue ) pfe/tools-mix.c

the upper limit of the forth writeable memory space, the variable DICTLIMIT must be below this line. stack-space and other space-areas are often allocated above DICTLIMIT upto this constant.

DICTFENCE is the lower end of the writeable dictionary

p4_paren_dictfence --- : FCode
(DICTFENCE) ( -- constvalue ) pfe/tools-mix.c

the lower limit of the forth writeable memory space, the variable DICTFENCE must be above this line. Some code-areas are often moved in between DICTFENCE and this constant. To guard normal Forth code from deletion the usual practice goes with the FENCE variable

DICTLIMIT is the upper end of the writeable dictionary

p4_Q_file_open(p4_File *fid) : _export void
 ... pfe/tools-sub.c
p4_abortq(const char *fmt,...) : _export void
 ... pfe/tools-sub.c
p4_to_compile(p4xt xt) : void
  pfe/useful-ext.c

see >COMPILE and POSTPONE

p4_prefix_begin --- : FCode
"($" ( [word] -- cs-token ) compile-only pfe/useful-ext.c

takes the execution token of the following word and saves it on the compile-stack. The correspondig closing ) will then feed it into >COMPILE - so this pair of word provides you with a prefix-operation syntax that you may have been seen in lisp-like languages.

    ($ IF ($ 0= A1 @ )) ($ THEN ." hello " )

Note that an opening simple ( paren is a comment.

p4_prefix_end --- : FCode
")" ( cs-token -- ) pfe/useful-ext.c

takes the execution-token from ($ and compiles it using >COMPILE

p4_prefix_end_doubled --- : FCode
"))" ( cs-token cs-token -- ) pfe/useful-ext.c

takes two execution-tokens from two of ($ and compiles them on after another using >COMPILE

  simulate:
     : )) [COMPILE] ) [COMPILE] ) ; IMMEDIATE
  
p4_sprintf --- : FCode
PFE-SPRINTF ( args ... format$ dest$ -- len-dest ) pfe/useful-ext.c

just like the standard sprintf() function in C, but the format is a counted string and accepts %#s to be the format-symbol for a forth-counted string. The result is a zeroterminated string at dest$ having a length being returned. To create a forth-counted string, you could use:

    variable A 256 ALLOT
    15 " example" " the %#s value is %i" A 1+ SPRINTF A C!
    A COUNT TYPE
  
p4_printf --- : FCode
PFE-PRINTF ( args ... format$ -- ) pfe/useful-ext.c

uses SPRINTF to print to a temporary 256-char buffer and prints it to stdout afterwards. See the example at SPRINTF of what it does internally.

p4_loadf --- : FCode
LOADF ( "filename" -- ) pfe/useful-ext.c

loads a file just like INCLUDE but does also put a MARKER in the LOADED dictionary that you can do a FORGET on to kill everything being loaded from that file.

p4_paren_loadf_locate --- : FCode
"(LOADF-LOCATE)" ( xt -- nfa ) pfe/useful-ext.c

the implementation of LOADF-LOCATE

p4_loadf_locate --- : FCode
LOADF-LOCATE ( "name" -- ) pfe/useful-ext.c

look for the filename created by LOADF that had been defining the given name. LOADF has created a marker that is above the INCLUDED file and that marker has a body-value just below the INCLUDED file. Hence the symbol was defined during LOADF execution of that file.

  : LOADF-LOCATE ?EXEC POSTPONE ' (LOADF-LOCATE) .NAME ;
  
p4_semicolon_and_execution --- : FCode_XE
"(;AND)" ( -- ) pfe/useful-ext.c

compiled by ;AND

p4_semicolon_and --- : FCode
";AND" ( -- ) pfe/useful-ext.c

For the code piece between MAKE and ;AND , this word will do just an EXIT . For the code outside of the MAKE construct a branch-around must be resolved then.

p4_make_to_local_execution --- : FCode_XE
"((MAKE-))" ( -- ) pfe/useful-ext.c

compiled by MAKE

p4_make_to_execution --- : FCode_XE
"((MAKE))" ( -- ) pfe/useful-ext.c

compiled by MAKE

p4_make --- : FCode
MAKE ( [word] -- ) ... ;AND pfe/useful-ext.c

make a seperated piece of code between MAKE and ;AND and on execution of the MAKE the named word is twisted to point to this piece of code. The word is usually a DOER but the current implementation works on DEFER just as well, just as it does on other words who expect to find an execution-token in its PFA. You could even create a colon-word that starts with NOOP and can then make that colon-word be prefixed with the execution of the code piece. This MAKE does even work on LOCALS| and VAR but it is uncertain what that is good for.

p4_offset_RT --- : FCode_RT
OFFSET-RT ( value -- value+offset ) pfe/useful-ext.c

this runtime will add the body-value to the value at top-of-stack. used heavily in structure access words, compiled by /FIELD

p4_offset_constant --- : FCode
+CONSTANT ( offset "name" -- ) pfe/useful-ext.c

create a new offsetword. The word is created and upon execution it adds the offset, ie. compiling the OFFSET-RT runtime:

        ( address -- address+offset )

This word is just a convenience word, just use the word +FIELD directly and choose a DROP to flag the end of a current offset-field declaration series. See also /FIELD series to declare simple structures which end with a final CONSTANT to memorize the complete size. The /FIELD style is more traditional.

p4_plus_field --- : FCode
+FIELD: ( offset "name" -- offset ) pfe/useful-ext.c

created a new name with an OFFSET-RT runtime using the given offset. Leave the offset-value untouched, so it can be modified with words like CHAR+ and CELL+ and SFLOAT+ ; This word is the simplest way to declared structure access words in forth - the two STRUCT modules contain a more elaborate series of words. Use this one like:

  0                        ( a fresh definition is started )
  +FIELD: zapp.a+ CHAR+     ( zero offset from the base of the struct )
  +FIELD: zapp.b+ CELL+     ( no alignment, starts off at 1 from base )
  +FIELD: zapp+   DROP      ( store size of complete zap structure )
 
  0 zapp+                  ( extend the zap structure )
  +FIELD: zappx.c+ CELL+    ( a new field )
  +FIELD: zappx+   DROP     ( and save it again )
 
  CREATE zapp1  0 zapp+ ALLOT ( a way to allocate a strucutre )
 
  zapp2 zapp.b+ @         ( read a value from the field )
  16 zapp2 zapp.b+ !      ( store a value in there )
 

this form is not the traditional form used in forth, it is however quite simple. Use the simplefield declaration with /FIELD to be compatible with traditional styles that build on top of sizeof constants in forth (which are not part of the ANS Forth standard).

p4_slash_field --- : FCode
/FIELD ( offset size "name" -- offset+size ) pfe/useful-ext.c

created a new +FIELD name with an OFFSET-RT of offset. Then add the size value to the offset so that the next /FIELD declaration will start at the end of the field currently declared. This word is the simplest way to declared structure access words in forth - the two STRUCT modules contain a more elaborate series of words. This one is used like:

  0                        ( a fresh definition is started )
  /CHAR /FIELD ->zapp.a    ( zero offset from the base of the struct )
  /CELL /FIELD ->zapp.b    ( no alignment, starts off at 1 from base )
  CONSTANT /zapp           ( store size of complete zap structure )
 
  /zapp                    ( extend the zap structure )
  /CELL /FIELD ->zappx.c   ( a new field )
  CONSTANT /zappx          ( and save it again )
 
  CREATE zapp1 /zapp ALLOT ( a way to allocate a strucutre )
  /zapp BUFFER: zapp2      ( another way to do it, semi-standard )
 
  zapp2 ->zapp.b @         ( read a value from the field )
  16 zapp2 ->zapp.b !      ( store a value in there )
 

compare also with /CHAR /WCHAR /CELL /DCELL and use +FIELD as the lowlevel word, can simulate as

  : /FIELD SWAP +FIELD + ;
  
p4_bracket_not --- : FCode
[NOT] ( a -- a' ) pfe/useful-ext.c

executes 0= but this word is immediate so that it does affect the cs-stack while compiling rather than compiling anything. This is useful just before words like [IF] to provide semantics of an [IFNOT]. It is most useful in conjunction with "=> [DEFINED] word" as it the sequence "[DEFINED] word [NOT] [IF]" can simulate "[IFNOTDEF] word"

p4_replace_in --- : FCode
REPLACE-IN ( to-xt from-xt n "name" -- ) pfe/useful-ext.c

will handle the body of the named word as a sequence of cells (or tokens) and replaces the n'th occurences of from-xt into to-xt. A negative value will change all occurences. A zero value will not change any.

p4_x_quote --- : FCode
'X"' ( "hex-q" -- bstring ) pfe/useful-ext.c

places a counted string on stack containing bytes specified by hex-string - the hex string may contain spaces which will delimit the bytes

  example: 
     X" 41 42 4344" COUNT TYPE ( shows ABCD )
  
p4_evaluate_with --- : FCode
EVALUATE-WITH ( i*x addr len xt[i*x--j*x] -- j*x ) pfe/useful-ext.c

added to be visible on the forth command line on request by MLG, he has explained the usage before a lot, you can get an idea from:

     : EVALUATE ['] INTERPRET EVALUATE-WITH ;

The word is used internally in PFE for the loadlist evaluation of the binary modules: where previously each loadercode had its own CREATE-execution we do now call the original forthish CREATE-word like, so bootstrapping a VARIABLE will now call VARIABLE itself and of course we need to set up the TIB-area to point to the name of the variable that shall be created in the forth dictionary:

  : LOAD-WORD ( arg-value str-ptr str-len loader-code -- )
       CASE
         #LOAD-VARIABLE OF ['] VARIABLE EVALUATE-WITH ENDOF
         ....
       ENDCASE
       CLEARSTACK
  ;
  
p4_bracket_vocabulary --- : FCode
[VOCABULARY] ( "name" -- ) pfe/useful-ext.c

create an immediate vocabulary. Provides for basic modularization.

  : [VOCABULARY] VOCABULARY IMMEDIATE ;
  
p4_bracket_possibly --- : FCode
[POSSIBLY] ( [name] -- ?? ) pfe/useful-ext.c

check if the name exists, and execute it immediatly if found. Derived from POSSIBLY as seen in other forth systems.

  : [POSSIBLY] (') ?DUP IF EXECUTE THEN ; IMMEDIATE
  
p4_bracket_def --- : FCode
[DEF] ( -- ) pfe/useful-ext.c

immediatly set topmost CONTEXT voc to CURRENT compilation voc.

  : DEF' CURRENT @ CONTEXT ! ; IMMEDIATE

note that in PFE most basic vocabularies are immediate, so that you can use a sequence of

  FORTH ALSO  DEFINITIONS
  [DEF] : GET-FIND-3  [ANS] ['] FIND  [FIG] ['] FIND  [DEF] ['] FIND ;

where the first wordlist to be searched via the search order are [ANS] and [FIG] and FORTH (in this order) and which may or may not yield different flavours of the FIND routine (i.e. different XTs)

p4_context_Q --- : FCode
CONTEXT? ( -- number ) pfe/useful-ext.c

GET-CONTEXT and count how many times it is in the order but the CONTEXT variable itself. The returned number is therefore minus one the occurences in the complete search-order. usage:

    ALSO EXTENSIONS CONTEXT? [IF] PREVIOUS [THEN]
    ALSO DEF' DEFAULT-ORDER
  : CONTEXT? 
    0 LVALUE _count
    GET-ORDER 1- SWAP  LVALUE _context
    0 ?DO _context = IF 1 +TO _count THEN LOOP
    _count
  ;
  
p4_defs_are_case_sensitive --- : FCode
DEFS-ARE-CASE-SENSITIVE ( -- ) pfe/useful-ext.c

accesses CURRENT which is generally the last wordlist that the DEFINITIONS shall go in. sets there a flag in the vocabulary-definition so that words are matched case-sensitive.

  example: 
     VOCABULARY MY-VOC  MY-VOC DEFINITIONS DEFS-ARE-CASE-SENSITIVE
  
p4_case_sensitive_voc --- : FCode
CASE-SENSITIVE-VOC ( -- ) pfe/useful-ext.c

accesses CONTEXT which is generally the last named VOCABULARY . sets a flag in the vocabulary-definition so that words are matched case-sensitive.

  example: 
     VOCABULARY MY-VOC  MY-VOC CASE-SENSITIVE-VOC

OBSOLETE! use DEFS-ARE-CASE-SENSITIVE

p4_defs_are_searched_also --- : FCode
DEFS-ARE-SEARCHED-ALSO ( -- ) pfe/useful-ext.c

binds CONTEXT with CURRENT. If the CURRENT VOCABULARY is in the search-order (later), then the CONTEXT vocabulary will be searched also. If the result of this word could lead into a recursive lookup with FIND it will throw CURRENT_DELETED and leave the CURRENT VOCABULARY unaltered.

  example:

MY-VOC DEFINITIONS MY-VOC-PRIVATE DEFS-ARE-SEARCHED-ALSO

p4_bracket_execute --- : FCode
[EXECUTE] ( [word] -- ) pfe/useful-ext.c

ticks the following word, and executes it - even in compiling mode.

  : [EXECUTE] ' EXECUTE ;
  
p4_spy_on --- : FCode
SPY_ON ( -- ) pfe/with-spy.c

change the runtime-code of (NEST) to call a special word that prints info to the screen whenever a colon word is entered. It will print the name and the current stack, and results in a kind of execution trace over SPY' :-colon nested words.

p4_spy_off --- : FCode
SPY_OFF ( -- ) pfe/with-spy.c

disable SPY_ON nest-trace.

p4_spy_colon_RT --- : FCode_RT
"SPY' (NEST)" ( -- ) pfe/with-spy.c

compiled by :

p4_spy_colon --- : FCode
"SPY:" ( name -- ) pfe/with-spy.c

create a header for a nesting word and go to compiling mode then. This word is usually ended with ; but the execution of the resulting colon-word can also return with EXIT this is the spy-version SPY_ON

p4_spy_semicolon --- : FCode
";SPY" ( -- ) pfe/with-spy.c

compiles ((;)) which does EXIT the current colon-definition. It does then end compile-mode and returns to execute-mode. See : and :NONAME

p4_spy_exit --- : FCode
"SPY-EXIT" ( -- ) pfe/with-spy.c

will unnest the current colon-word so it will actually return the word calling it. This can be found in the middle of a colon-sequence between : and ;

p4_tick_from --- : FCode
"'>" ( [name] -- xt ) pfe/your-ext.c

get the execution-token, ie the CFA, of the word following. This word is fully state-smart while the ANSI standard words namely ' and ['] are not.

p4_fetch_from --- : FCode
@> ( [name] -- value ) pfe/your-ext.c

does fetch the value from the PFA of the named item, which may be about everything, including a VARIABLE , VALUE LVALUE , LOCALS| , VAR , DEFER , DOER , DOES> and more.

p4_into_execution --- : FCode_XE
((INTO)) pfe/your-ext.c

execution compiled by INTO

p4_into_local_execution --- : FCode_XE
((INTO-)) ( -- value ) pfe/your-ext.c

execution compiled by INTO

p4_into --- : FCode
INTO ( [name] -- pfa ) pfe/your-ext.c

will return the parameter-field address of the following word. Unlike others, this word will also return the address of LOCALS| and local LVALUE - so in fact a TO A and INTO A ! are the same. This word is most useful when calling C-exported function with a temporary local-VAR as a return-place argument - so the address of a local has to be given as an arg. Beware that you should not try to save the address anywhere else, since a local's address does always depend of the RP-depth - EXIT from a colon-word and the value may soon get overwritten. (see also TO )

p4_dot_h2 --- : FCode
.H2 ( value -- ) pfe/your-ext.c

print hexadecimal, but with per-byte 0-padding

    0x0     -> 00
    0xf     -> 0f
    0x12    -> 12
    0x123   -> 0123
    0x1234  -> 1234
    0x12345 -> 012345
  
p4_here_word --- : FCode
HERE-WORD ( char "name" -- ) pfe/your-ext.c

a FIG-compatible WORD. Where ANSI says "skip leading delimiters" this one acts as "skip leading whitespace". And it will not return anything and have the string parsed to HERE

p4_z_quote --- : FCode
'Z"' ( [chars<">] -- z* ) pfe/zchar-ext.c

scan the input to the next doublequote and create a buffer that holds the chars - return the address of that zero-terminated string-buffer, either POCKET-PAD or ALLOTed into the dictionary.

p4_zcount --- : FCode
ZCOUNT ( z* -- z* len ) pfe/zchar-ext.c

push length of z-string, additionally to the string addr itself.

  : ZSTRLEN ZCOUNT NIP ;

(see libc strlen(3)) / compare with COUNT / ZSTRLEN

p4_zstrlen --- : FCode
ZSTRLEN ( z* -- len ) pfe/zchar-ext.c

push length of z-string.

  : ZSTRLEN ZCOUNT NIP ;

(see libc strlen(3)) / compare with ZMOVE / CMOVE

p4_zmove --- : FCode
ZMOVE ( zsrc* zdest* -- ) pfe/zchar-ext.c

copy a zero terminated string (see libc strcpy(3)) / compare with ZSTRLEN / COUNT

p4_appendz --- : FCode
+ZPLACE ( caddr* u zdest* -- ) pfe/zchar-ext.c

Add the string defined by CADDR LEN to the zero terminated string at ZDEST - (for older scripts the SYNONYM named APPENDZ exists) (see libc strncat(3)) / compare with ZPLACE / +PLACE

p4_zplace --- : FCode
ZPLACE ( addr* len zaddr* -- ) pfe/zchar-ext.c

copy string and place as 0 terminated (see libc strncpy(3)) / see also +ZPLACE / Z+PLACE

p4_c_backslash_quote --- : FCode
'C\\\"' ( [backslashed-strings_<">] -- bstr* ) pfe/zchar-ext.c

scan the following text to create a literal just like C" does, but backslashes can be used to escape special chars. The rules for the backslashes follow C literals, implemented techniques are \n \r \b \a \f \v \e \777 and all non-alnum chars represent themselves, esp. \" \' \ \? \! \% \( \) \[ \] \{ \} etcetera. most importantly the doublequote itself can be escaped. but be also informed that the usage of \' and \" is not portable as some systems preferred to map [\'] into ["]. Here I use the experimental addition to map [\q] to ["] and [\i] to [']

p4_s_backslash_quote --- : FCode
'S\\\"' ( [backslashed-strings_<">] -- str cnt ) pfe/zchar-ext.c

scan the following text to create a literal just like S" does, but backslashes can be used to escape special chars. The rules for the backslashes follow C literals, implemented techniques are \n \r \b \a \f \v \e \777 and all non-alnum chars represent themselves, esp. \" \' \ \? \! \% \( \) \[ \] \{ \} etcetera. most importantly the doublequote itself can be escaped. but be also informed that the usage of \' and \" is not portable as some systems preferred to map [\'] into ["]. Here I use the experimental addition to map [\q] to ["] and [\i] to [']

p4_z_backslash_quote --- : FCode
'Z\\\"' ( [backslashed-strings_<">] -- zstr* ) pfe/zchar-ext.c

scan the following text to create a literal just like Z" does, but backslashes can be used to escape special chars. The rules for the backslashes follow C literals, implemented techniques are \n \r \b \a \f \v \e \777 and all non-alnum chars represent themselves, esp. \" \' \ \? \! \% \( \) \[ \] \{ \} etcetera. most importantly the doublequote itself can be escaped but be also informed that the usage of \' and \" is not portable as some systems preferred to map [\'] into ["]. Here I use the experimental addition to map [\q] to ["] and [\i] to [']