word def state can enter state now

This commit is contained in:
Richard Thier 2024-09-28 12:57:01 +02:00
parent 71619a7fde
commit 4889472dd3
2 changed files with 57 additions and 7 deletions

View File

@ -4,6 +4,7 @@
#include<stdint.h> // uint8_t, uint32_t..
#include<string.h> // memcpy, strlen..
#include<stddef.h> // NULL
#include<ctype.h> // isspace
/* Define this if you want to debug the engine doing its thing */
/* #define SLC_DEBUG */
@ -13,7 +14,7 @@
#define SLOFFS_T uint64_t
#endif
/* Maximum length of words - defaults but you can override */
/* Maximum length of words - defaults but you can override; Adds +1 to this for null terminator */
#ifndef SL_MAX_WORD_NAME
#define SL_MAX_WORD_NAME 255
#endif
@ -270,6 +271,8 @@ enum slc_state : uint8_t {
SLC_WORD_NAME = 'w',
/** Variable call (MYWORD@MYVAR) - we get to be here from SLC_WORD_NAME or from START */
SLC_WORD_VAR = 'W',
/** Syntax error state - recovers by newlines */
SLC_SYN_ERROR = 'e',
};
typedef enum slc_state slc_state;
@ -326,15 +329,45 @@ static inline slc_state slc_multiline_comment_statechange_out(
return current_state;
}
/** Handles state change into word definitions */
static inline slc_state slc_def_name_statechange(
slc_state current_state,
char prevc,
char c,
const char *prefix,
int *prefix_i) {
// FIXME: Implement
return current_state;
/* If not a whitespace currently, check the prefix, otherwise check ending ':' */
if(!isspace(c)) {
/* Early exit for not-a-definition sub-state */
if(*prefix_i < 0) {
return current_state;
}
/* Read prefix */
if(prefix[*prefix_i] != 0) {
if(prefix[*prefix_i] == c) {
++(*prefix_i);
} else {
*prefix_i = -1;
}
}
return current_state;
} else {
/* Check if ended by ':' after full prefix or not */
if(prevc == ':' && (*prefix_i > 0) && prefix[*prefix_i] == 0) {
/* Found: a word definition! */
return SLC_WORD_NAME;
} else {
/* Not Found: Probably a word occurence */
*prefix_i = 0; /* XXX: restarts scan */
return current_state;
}
}
}
/** Handles state change into word occurences - shared wordname with def_name_statechange! */
static inline slc_state slc_word_statechange(
slc_state current_state,
char c,
@ -412,13 +445,15 @@ static inline void slc(
int multiline_i = 0;
int prefix_i = 0;
int wordname_i = 0;
char wordname[SL_MAX_WORD_NAME];
char wordname[SL_MAX_WORD_NAME + 1];
char prevc = 0;
char c = 0;
while(((c = code_src()) != 0)) {
/* Handle lines and columns, parts of indenting */
if(endsline(c)) {
if(!last_is_endl) {
/* Handles \n, \r, \r\n and \n\r this way and counts empty lines properly */
if((prevc != c) || !last_is_endl) {
++line;
col = 0;
/* Indent part */
@ -454,6 +489,7 @@ static inline void slc(
if(state == SLC_START) {
state = slc_def_name_statechange(
state,
prevc,
c,
prefix,
&prefix_i);
@ -489,7 +525,13 @@ static inline void slc(
break;
case SLC_WORD_VAR:
break;
case SLC_SYN_ERROR:
/* Recover from slc syntax errors at endlines for now */
if(endsline(c)) state = SLC_START;
break;
}
prevc = c;
}
}

12
main.c
View File

@ -29,12 +29,20 @@ iores nopioconn(SLC_IO_OP op, const char *param) {
char testcoderead() {
static int i = 0;
static const char *code =
"// This is a small test program push(42)\n"
"// This is a small test program to push(42); print\n"
"/*#push(21)\n"
"#push(21)\n"
"#add*/\n"
" #push(42)\n"
" #print\n";
" #print\n"
"\n"
"#: word_test\n"
" #push(21)\n"
" #push(21)\n"
" #add\n"
" #print\n"
"\n"
"word_test\n";
return code[i++];
}