diff --git a/engine/slc.h b/engine/slc.h index 99a7264..d498493 100644 --- a/engine/slc.h +++ b/engine/slc.h @@ -1,15 +1,81 @@ #ifndef SLC_H #define SLC_H -/** A word starts right after this - a word is usually after this memory area */ +/** Possible word types */ +enum SLC_WORDTYP { + /** Still in plain text */ + SLC_WORDTYP_TEXT = 0, + /** Native code, use get_word_storage_offset to get what to run (relative pointer or array of pointers) */ + SLC_WORDTYP_NATIVE = 1, + /** "Threaded code" (utf16-like word offsets) and encoded parentheses IN-PLACE inlined where text was before */ + SLC_WORDTYP_THREADED_INLINE = 2, + /** "Threaded code" that did not fit in-place and is thus stored in session storage, word offset tells where */ + SLC_WORDTYP_THREADED_SESSION = 2 +}; +typedef enum SLC_WORDTYP SLC_WORDTYP; + +/** Gets the wordtyp from a flags field - see wordstart */ +static inline SLC_WORDTYP get_word_type(uint8_t flags) { + return (SLC_WORDTYP)(flags >> 6); +} + +/** Gets the 6-bit variable count (at most 64 vars possible per word) */ +static inline uint8_t get_word_var_count(uint8_t flags) { + return (flags && 0x3F); /* 0011 1111 */ +} + +/** Gets the 24bit storage offset of the word: Natives contain pointers in an offseted array */ +static inline uint32_t get_word_storage_offset(uint8_t high_offset, uint16_t low_offset) { + return ((uint32_t)high_offset << 16) + low_offset; +} + +/** + * A word definition starts right after this. After processing it, we inline overwrite random parts of it in memory... + * + * Examples: + * + * #: just_code + * #dup + * #inc + * #swap + * # + * + * : with_vars @a; @b; @c; + * @a + * inc + * @a(.) + * ; + * + * #builtin: to_prefix + * #swap + * #dup + * + * TODO: How to do this builtin to be properly changed inline? If it can be inline threaded-coded, then its fine, but is spec-case + * ^^The above always needs starting '#builtin' at the definition and inside. That is exchanged to real prefix... + * This is used for implementation implementing built-ins with FORTH-like code instead of native (saves native interpret. space) + * + * #: structural ( + * #parse_num + * #dup + * #inc + * #swap + * #print + * #print + * ) [ #parse_num #print ] { #parse_num #print } + * # + */ struct wordstart { - /* : */ - char colon; - /* whitespace after ':', usually used to store the flags */ + /** The ':' char - after processing it stores the flags */ uint8_t flags; - /* char name[]; // The name of the word being defined. */ - /* char vars[]; // The local variables of the word. */ - /* char data[]; // The "body" of the word - either text source or after processing the threaded code of it (see flags) */ + /** whitespace after ':' and first char of name - after processing contains the high-offset */ + uint16_t high_offset; + /** Either remaining parts of the name - or the leading tab/space for starting variables (or newline if there's none) */ + uint8_t low_offset; + /* char ..name[]; // The REMAINS of name of the word being defined. Can be empty! */ + /* char vars[]; // The local (at least 1-letter) variables of the word. Can be empty - min 4x8bit per a var, like: " @a;" */ + /* char newline; // there is always a newline at this point! XXX: "@a; ", "@b;\n" is how we store vars (*/ + /* char data[]; // The "body" of the word - either text source or inline threaded code (at least 1 character) */ + /* char ender[]; // The ender-string that ends the word - always at least 1 character! */ }; typedef struct wordstart wordstart; @@ -128,8 +194,11 @@ typedef uint32_t (*coderead)(SLC_CODE_OP op, uint32_t i); * @param insert_stack Used for temporarily expanding the input stream (one word level above) with words * @param session_storage Can allocate and use arbitrary memory with this. * @param io_connector The engine uses this to open/close pipes/files and write/read them. + * @param prefix The prefix added to the lookup of built-ins. + * @param ender The character string that ends a word definition. + * @param varprefix The character string that prefixes variable declarations. */ -void slc( +static inline void slc( coderead code_src, sym symbol_table, stack code_stack,