Compare commits
4 Commits
844a9165dd
...
5d2f0d187b
Author | SHA1 | Date | |
---|---|---|---|
|
5d2f0d187b | ||
|
aaa8b2fb9c | ||
|
d35b55194f | ||
|
ceabdee697 |
76
engine/slc.h
76
engine/slc.h
@ -5,6 +5,9 @@
|
||||
#include<string.h> // memcpy, strlen..
|
||||
#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 */
|
||||
#ifndef SLOFFS_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);
|
||||
|
||||
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;
|
||||
/** The read character */
|
||||
char c;
|
||||
@ -226,8 +229,8 @@ typedef union iores iores;
|
||||
* 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_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_WRITE Writes a character from the given file handle. The 'param' points to the character to write (1 byte)
|
||||
* 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 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_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.
|
||||
@ -243,23 +246,24 @@ typedef iores (*ioconn)(SLC_IO_OP op, const char *param);
|
||||
*/
|
||||
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 */
|
||||
SLC_START,
|
||||
SLC_START = 's',
|
||||
/** In a comment */
|
||||
SLC_COMMENT,
|
||||
SLC_COMMENT = 'c',
|
||||
/** In multi-line comment */
|
||||
SLC_MULTILINE_COMMENT,
|
||||
SLC_MULTILINE_COMMENT = 'm',
|
||||
/** 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 */
|
||||
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 */
|
||||
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 */
|
||||
SLC_WORD_NAME,
|
||||
SLC_WORD_NAME = 'w',
|
||||
/** 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;
|
||||
|
||||
@ -268,11 +272,30 @@ static inline slc_state slc_comment_statechange_in(
|
||||
char c,
|
||||
const char *singleline_comment,
|
||||
const char *multiline_comment_opener,
|
||||
int singleline_comment_len,
|
||||
int multiline_comment_len,
|
||||
int *comment_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;
|
||||
}
|
||||
|
||||
@ -350,13 +373,14 @@ static inline void slc(
|
||||
const char *ender,
|
||||
const char *varprefix) {
|
||||
|
||||
slc_state state = SLC_START;
|
||||
int singleline_comment_len = strlen(singleline_comment);
|
||||
int multiline_comment_opener_len = strlen(multiline_comment_opener);
|
||||
char last_is_endl = 0;
|
||||
int line = 0;
|
||||
int col_plus_one = -1;
|
||||
|
||||
// TODO: Count line numbers
|
||||
// TODO: Handle/count indentation for better error messages
|
||||
|
||||
slc_state state = SLC_START;
|
||||
|
||||
int comment_i = 0;
|
||||
int multiline_i = 0;
|
||||
int prefix_i = 0;
|
||||
@ -365,7 +389,19 @@ static inline void slc(
|
||||
|
||||
char c = 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:
|
||||
int col = col_plus_one;
|
||||
#ifdef SLC_DEBUG
|
||||
printf("%c state:%c @ line:%d col:%d\n", c, state, line, col);
|
||||
#endif
|
||||
switch(state) {
|
||||
case SLC_START:
|
||||
/* state -> comment | multiline_comment */
|
||||
@ -374,8 +410,6 @@ static inline void slc(
|
||||
c,
|
||||
singleline_comment,
|
||||
multiline_comment_opener,
|
||||
singleline_comment_len,
|
||||
multiline_comment_opener_len,
|
||||
&comment_i,
|
||||
&multiline_i);
|
||||
|
||||
|
54
main.c
54
main.c
@ -1,10 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <stddef.h> // NULL
|
||||
#include "hamt.h"
|
||||
#include "turbolist/turbolist.h"
|
||||
|
||||
#define SLC_DEBUG
|
||||
#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) {
|
||||
// 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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user