Compare commits

...

4 Commits

Author SHA1 Message Date
Richard Thier
5d2f0d187b line and column handling + better debug log 2024-09-26 13:05:38 +02:00
Richard Thier
aaa8b2fb9c added some test code to main.c 2024-09-26 12:32:58 +02:00
Richard Thier
d35b55194f added engine debugging and some cleanup 2024-09-26 12:32:34 +02:00
Richard Thier
ceabdee697 slc comment start state machine 2024-09-26 11:52:28 +02:00
2 changed files with 109 additions and 21 deletions

View File

@ -5,6 +5,9 @@
#include<string.h> // memcpy, strlen.. #include<string.h> // memcpy, strlen..
#include<stddef.h> // NULL #include<stddef.h> // NULL
/* Define this if you want to debug the engine doing its thing */
/* #define SLC_DEBUG */
/* Session offset type - defaults to 64 bit because of union types enable storage for it often, but you can override */ /* Session offset type - defaults to 64 bit because of union types enable storage for it often, but you can override */
#ifndef SLOFFS_T #ifndef SLOFFS_T
#define SLOFFS_T uint64_t #define SLOFFS_T uint64_t
@ -210,7 +213,7 @@ typedef uint32_t (*stack)(SLC_STACK_OP op, uint32_t param);
typedef uint32_t (*session)(SLC_SESSION_OP op, uint32_t i, uint32_t j); typedef uint32_t (*session)(SLC_SESSION_OP op, uint32_t i, uint32_t j);
union iores { union iores {
/** Either the terminal cmd result or the handle pointer */ /** Either the terminal cmd result or the handle pointer. NULL means some kind of error */
const char *ptr; const char *ptr;
/** The read character */ /** The read character */
char c; char c;
@ -226,8 +229,8 @@ typedef union iores iores;
* SLC_IO_CLOSE Closes a PERSISTENT file with the given handle. * SLC_IO_CLOSE Closes a PERSISTENT file with the given handle.
* SLC_IO_OPEN_TMP Opens a TEMPORARY file with the given name. Returns the handle pointer. * SLC_IO_OPEN_TMP Opens a TEMPORARY file with the given name. Returns the handle pointer.
* SLC_IO_CLOSE_TMP Removes the TEMPORARY file with the given handle. * SLC_IO_CLOSE_TMP Removes the TEMPORARY file with the given handle.
* SLC_IO_READ Reads a character from the given file handle. Returns pointer to the character that got read. * SLC_IO_READ Reads a character from the given file handle. Returns '\0' on EOF and being out of data!
* SLC_IO_WRITE Writes a character from the given file handle. The 'param' points to the character to write (1 byte) * SLC_IO_WRITE Writes a character to the given file handle. The 'param' points to the character to write (1 byte)
* SLC_IO_LOCK Locks the given file handle for exclusive reads and writes (others need to use lock/unlock too) * SLC_IO_LOCK Locks the given file handle for exclusive reads and writes (others need to use lock/unlock too)
* SLC_IO_UNLOCK Locks the given file handle for exclusive reads and writes (others need to use lock/unlock too) * SLC_IO_UNLOCK Locks the given file handle for exclusive reads and writes (others need to use lock/unlock too)
* SLC_IO_CMD Runs the given command on the operating system. The 'param' is the command (+args) and returned is std output. * SLC_IO_CMD Runs the given command on the operating system. The 'param' is the command (+args) and returned is std output.
@ -243,23 +246,24 @@ typedef iores (*ioconn)(SLC_IO_OP op, const char *param);
*/ */
typedef char (*coderead)(); typedef char (*coderead)();
enum slc_state : uint32_t { /** States the main state-engine can pick up - use characters for debugging better */
enum slc_state : uint8_t {
/** Before things */ /** Before things */
SLC_START, SLC_START = 's',
/** In a comment */ /** In a comment */
SLC_COMMENT, SLC_COMMENT = 'c',
/** In multi-line comment */ /** In multi-line comment */
SLC_MULTILINE_COMMENT, SLC_MULTILINE_COMMENT = 'm',
/** Name part of word-definition (after ':') - whitespace ends it */ /** Name part of word-definition (after ':') - whitespace ends it */
SLC_DEF_NAME, SLC_DEF_NAME = 'd',
/** Variable-listing part of word-definition - endline, '(', '[' or '{' ends it */ /** Variable-listing part of word-definition - endline, '(', '[' or '{' ends it */
SLC_DEF_VAR, SLC_DEF_VAR = 'D',
/** Raw body part of the word definition - these can contain local variable accesses + words, depth counted by vars */ /** Raw body part of the word definition - these can contain local variable accesses + words, depth counted by vars */
SLC_DEF_BODY, SLC_DEF_BODY = 'b',
/** Name part of a word "call" (non-definition). Ends by whitespace, '@' (in case of variable) or various parentheses */ /** Name part of a word "call" (non-definition). Ends by whitespace, '@' (in case of variable) or various parentheses */
SLC_WORD_NAME, SLC_WORD_NAME = 'w',
/** Variable call (MYWORD@MYVAR) - we get to be here from SLC_WORD_NAME or from START */ /** Variable call (MYWORD@MYVAR) - we get to be here from SLC_WORD_NAME or from START */
SLC_WORD_VAR, SLC_WORD_VAR = 'W',
}; };
typedef enum slc_state slc_state; typedef enum slc_state slc_state;
@ -268,11 +272,30 @@ static inline slc_state slc_comment_statechange_in(
char c, char c,
const char *singleline_comment, const char *singleline_comment,
const char *multiline_comment_opener, const char *multiline_comment_opener,
int singleline_comment_len,
int multiline_comment_len,
int *comment_i, int *comment_i,
int *multiline_i){ int *multiline_i){
// FIXME: Implement
char s = singleline_comment[*comment_i];
char m = multiline_comment_opener[*multiline_i];
/* Check if we have finished processing */
if(s == 0) return SLC_COMMENT;
if(m == 0) return SLC_MULTILINE_COMMENT;
/* Single-line comment progress */
if(c == s) {
++(*comment_i);
} else {
*comment_i = 0;
}
/* Multi-line comment progress */
if(c == m) {
++(*multiline_i);
} else {
*multiline_i = 0;
}
return current_state; return current_state;
} }
@ -350,13 +373,14 @@ static inline void slc(
const char *ender, const char *ender,
const char *varprefix) { const char *varprefix) {
slc_state state = SLC_START; char last_is_endl = 0;
int singleline_comment_len = strlen(singleline_comment); int line = 0;
int multiline_comment_opener_len = strlen(multiline_comment_opener); int col_plus_one = -1;
// TODO: Count line numbers
// TODO: Handle/count indentation for better error messages // TODO: Handle/count indentation for better error messages
slc_state state = SLC_START;
int comment_i = 0; int comment_i = 0;
int multiline_i = 0; int multiline_i = 0;
int prefix_i = 0; int prefix_i = 0;
@ -365,7 +389,19 @@ static inline void slc(
char c = 0; char c = 0;
while(((c = code_src()) != 0)) { while(((c = code_src()) != 0)) {
/* Handle lines and columns */
if(c == '\n' || c == '\r') {
if(!last_is_endl) {
++line;
col_plus_one = 0;
}
last_is_endl = 1;
} else { last_is_endl = 0; ++col_plus_one; }
process_char: process_char:
int col = col_plus_one;
#ifdef SLC_DEBUG
printf("%c state:%c @ line:%d col:%d\n", c, state, line, col);
#endif
switch(state) { switch(state) {
case SLC_START: case SLC_START:
/* state -> comment | multiline_comment */ /* state -> comment | multiline_comment */
@ -374,8 +410,6 @@ static inline void slc(
c, c,
singleline_comment, singleline_comment,
multiline_comment_opener, multiline_comment_opener,
singleline_comment_len,
multiline_comment_opener_len,
&comment_i, &comment_i,
&multiline_i); &multiline_i);

54
main.c
View File

@ -1,10 +1,64 @@
#include <stdio.h> #include <stdio.h>
#include <stddef.h> // NULL
#include "hamt.h" #include "hamt.h"
#include "turbolist/turbolist.h" #include "turbolist/turbolist.h"
#define SLC_DEBUG
#include "engine/slc.h" #include "engine/slc.h"
symptr nopsym(SLC_SYM_OP op, char *key, symptr ptr) {
symptr ret;
ret.worp = NULL;
return ret;
}
uint32_t nopstack(SLC_STACK_OP op, uint32_t param) {
return 0;
}
uint32_t nopsession(SLC_SESSION_OP op, uint32_t i, uint32_t j) {
return (uint32_t) -1;
}
iores nopioconn(SLC_IO_OP op, const char *param) {
iores ret;
ret.ptr = NULL;
return ret;
}
char testcoderead() {
static int i = 0;
static const char *code =
"// This is a small test program push(42)\n"
"/*#push(21)\n"
"#push(21)\n"
"#add*/\n"
"#push(42)\n"
"#print\n";
return code[i++];
}
int main(int argc, const char **argv) { int main(int argc, const char **argv) {
// TODO: Implement CLI frontend... // TODO: Implement CLI frontend...
puts("TODO: Implement CLI frontend..."); puts("TODO: Implement CLI frontend...");
// TODO: test code removal
slc(
testcoderead, // code_src
nopsession, // session_storage
nopsym, // symbol_table
nopstack, // code_stack
nopstack, // nesting_stack
nopstack, // data_stack
nopstack, // insert_stack
nopioconn, // io_connector
"//", // singleline_comment
"/*", // multiline_comment_opener
"*/", // multiline_comment_closer,
"#", // prefix
"#", // ender
"@" // varprefix
);
return 0; return 0;
} }