[ADD] Add comments and keychars

master
LoaD Accumulator 10 months ago
parent 5ca2a58207
commit a0b9073287
Signed by: lda
GPG Key ID: 6898757653ABE3E6

@ -70,32 +70,49 @@ modified() {
}
# Get all source files
SOURCE_FILES=$(find $SOURCE_DIR -type f -name "*.c")
TMP_FILES=$(find $OBJECT_DIR -type f -name "*.o")
compile_build() {
SOURCE_FILES=$(find $SOURCE_DIR -type f -name "*.c")
TMP_FILES=$(find $OBJECT_DIR -type f -name "*.o")
OBJECT_FILES=""
for FILE in $TMP_FILES; do
# Does the file has it's C counterpart?
BASENAME=${FILE#$OBJECT_DIR/}
BASENAME=$SOURCE_DIR/${BASENAME%.o}.c
OBJECT_FILES=""
if [ -f $BASENAME ]; then
OBJECT_FILES="$OBJECT_FILES $FILE"
CLEAN_BUILD=1
if [ -z "$TMP_FILES" ]; then
CLEAN_BUILD=0
else
for FILE in $TMP_FILES; do
# Does the file has it's C counterpart?
BASENAME=${FILE#$OBJECT_DIR/}
BASENAME=$SOURCE_DIR/${BASENAME%.o}.c
if [ -f $BASENAME ]; then
OBJECT_FILES="$OBJECT_FILES $FILE"
fi
done
fi
done
echo $CYTOPLASM_INC
for SOURCE_FILE in $SOURCE_FILES; do
BASENAME=${SOURCE_FILE#$SOURCE_DIR/}
MODIFIED=$(modified ${BASENAME%.c})
echo $CYTOPLASM_INC
for SOURCE_FILE in $SOURCE_FILES; do
BASENAME=${SOURCE_FILE#$SOURCE_DIR/}
MODIFIED=$(modified ${BASENAME%.c})
if [ $MODIFIED -eq 1 ]; then
echo "CC $BASENAME"
mkdir -p $OBJECT_DIR/$(dirname $BASENAME)
$CC -c $CFLAGS $SOURCE_FILE -o $OBJECT_DIR/${BASENAME%.c}.o
if [ $MODIFIED -eq 1 ]; then
echo "CC $BASENAME"
mkdir -p $OBJECT_DIR/$(dirname $BASENAME)
$CC -c $CFLAGS $SOURCE_FILE -o $OBJECT_DIR/${BASENAME%.c}.o
[ $CLEAN_BUILD -eq 0 ] && OBJECT_FILES="$OBJECT_FILES $OBJECT_DIR/${BASENAME%.c}.o"
fi
done
#OBJECT_FILES="$OBJECT_FILES $OBJECT_DIR/${BASENAME%.c}.o"
fi
done
cc $OBJECT_FILES $CYTOPLASM_LIB/cytoplasm.o -L$CYTOPLASM_LIB -lcytoplasm -o voltaire
}
cc $OBJECT_FILES $CYTOPLASM_LIB/cytoplasm.o -L$CYTOPLASM_LIB -lcytoplasm -o voltaire
compile_clean() {
rm -rf voltaire $OBJECT_DIR/*
}
if [ -z $1 ]; then
compile_build
else
compile_$1
fi

@ -1,3 +1,7 @@
if true
else
false
# Here's a Voltaire comment
# ... maybe another one
if(true) {
# do something if it's true
} else {
# otherwise, do something else
}

@ -12,9 +12,29 @@ typedef struct LexerToken LexerToken;
#define TOKENS X(TOKEN_TRUE) \
X(TOKEN_FALSE) \
X(TOKEN_IF) \
X(TOKEN_ELSE)
X(TOKEN_ELSE) \
X(TOKEN_O_PARENTH) \
X(TOKEN_C_PARENTH) \
X(TOKEN_O_CBRACKT) \
X(TOKEN_C_CBRACKT) \
X(TOKEN_O_PBRACKT) \
X(TOKEN_C_PBRACKT) \
X(TOKEN_PLUS) \
X(TOKEN_MINUS) \
X(TOKEN_STAR) \
X(TOKEN_DIV) \
X(TOKEN_LT) \
X(TOKEN_GT) \
X(TOKEN_EQUAL) \
X(TOKEN_NOT) \
X(TOKEN_AND) \
X(TOKEN_OR) \
X(TOKEN_COLON) \
X(TOKEN_SEMICOLON) \
X(TOKEN_COMMA) \
X(TOKEN_DOT)
typedef enum LexerTokenType {
TOKENS TOKEN_EOF
TOKENS TOKEN_ERROR, TOKEN_EOF
} LexerTokenType;
#undef X

@ -8,7 +8,7 @@
#define X(x) #x,
const char * TOKEN_NAME[] = {
TOKENS "EOF"
TOKENS "[Invalid token]", "EOF"
};
typedef struct LexerSymbol {
@ -16,6 +16,11 @@ typedef struct LexerSymbol {
LexerTokenType type;
} LexerSymbol;
typedef struct LexerKeychar {
char c;
LexerTokenType type;
} LexerKeychar;
typedef enum State {
STATE_NONE = 0
} State;
@ -93,6 +98,100 @@ IsWhitespace(int c)
{
return (c == EOF) || (c == ' ') || (c == '\t') || (c == '\n');
}
extern LexerToken *
LexerReturnSymbol(LexerState * state, LexerTokenType type)
{
LexerToken * ret = NULL;
if (!state)
{
return NULL;
}
ret = Malloc(sizeof(LexerToken));
ret->type = type;
ret->line = state->savedLine;
ret->column = state->savedColumn;
ret->magic = NULL;
return ret;
}
static LexerToken *
LexerReturnEOF(LexerState * state)
{
LexerToken * ret = NULL;
if (!state)
{
return NULL;
}
ret = Malloc(sizeof(LexerToken));
ret->type = TOKEN_EOF;
ret->line = state->savedLine;
ret->column = state->savedColumn;
ret->magic = NULL;
return ret;
}
const static LexerSymbol symbols[] = {
{ .string = "true", .type = TOKEN_TRUE },
{ .string = "false", .type = TOKEN_FALSE },
{ .string = "if", .type = TOKEN_IF },
{ .string = "else", .type = TOKEN_ELSE }
};
const static LexerKeychar keychars[] = {
{ .c = '(', .type = TOKEN_O_PARENTH },
{ .c = ')', .type = TOKEN_C_PARENTH },
/* Curly brackets */
{ .c = '{', .type = TOKEN_O_CBRACKT },
{ .c = '}', .type = TOKEN_C_CBRACKT },
/* Pointy brackets */
{ .c = '[', .type = TOKEN_O_PBRACKT },
{ .c = ']', .type = TOKEN_C_PBRACKT },
/* Arithmetic symbols. */
{ .c = '+', .type = TOKEN_PLUS },
{ .c = '-', .type = TOKEN_MINUS },
{ .c = '*', .type = TOKEN_STAR },
{ .c = '/', .type = TOKEN_DIV },
/* Comparaison symbols */
{ .c = '>', .type = TOKEN_LT },
{ .c = '<', .type = TOKEN_GT },
{ .c = '=', .type = TOKEN_EQUAL },
/* Logical symbols */
{ .c = '!', .type = TOKEN_NOT },
{ .c = '&', .type = TOKEN_AND },
{ .c = '|', .type = TOKEN_OR },
/* Other */
{ .c = ':', .type = TOKEN_COLON },
{ .c = ';', .type = TOKEN_SEMICOLON },
{ .c = ',', .type = TOKEN_COMMA },
{ .c = '.', .type = TOKEN_DOT }
};
#define SYMBOL_COUNT (sizeof(symbols) / sizeof(LexerSymbol))
#define KEYCHAR_COUNT (sizeof(keychars) / sizeof(LexerKeychar))
static int
IsKeychar(int c)
{
long i;
for (i = 0; i < KEYCHAR_COUNT; i++)
{
if (c == keychars[i].c)
{
return keychars[i].type;
}
}
return -1;
}
/* Tries to match for a symbol */
static int
MatchSymbol(LexerState * state, const char * str)
@ -126,7 +225,8 @@ MatchSymbol(LexerState * state, const char * str)
goto end;
}
}
if (!IsWhitespace((undo[length] = LexerGetc(state))))
undo[length] = LexerGetc(state);
if (!(IsWhitespace(undo[length]) || IsKeychar(undo[length])))
{
for (j = length; j >= 0; j--)
{
@ -136,54 +236,12 @@ MatchSymbol(LexerState * state, const char * str)
}
ret = 1;
LexerUngetc(state, undo[length]);
end:
Free(undo);
return ret;
}
extern LexerToken *
LexerReturnSymbol(LexerState * state, LexerTokenType type)
{
LexerToken * ret = NULL;
if (!state)
{
return NULL;
}
ret = Malloc(sizeof(LexerToken));
ret->type = type;
ret->line = state->savedLine;
ret->column = state->savedColumn;
ret->magic = NULL;
return ret;
}
static LexerToken *
LexerReturnEOF(LexerState * state)
{
LexerToken * ret = NULL;
if (!state)
{
return NULL;
}
ret = Malloc(sizeof(LexerToken));
ret->type = TOKEN_EOF;
ret->line = state->line;
ret->column = state->column;
ret->magic = NULL;
return ret;
}
const static LexerSymbol symbols[] = {
{ .string = "true", .type = TOKEN_TRUE },
{ .string = "false", .type = TOKEN_FALSE },
{ .string = "if", .type = TOKEN_IF },
{ .string = "else", .type = TOKEN_ELSE }
};
const char *keychars = "({[,:;*/+-~|^]})";
#define SYMBOL_COUNT (sizeof(symbols) / sizeof(LexerSymbol))
LexerState *
LexerCreate(Stream * stream, int close)
@ -225,7 +283,12 @@ LexerTokenInfo(LexerToken * token)
{
return;
}
Log(LOG_INFO, "Token %s at line %d, column %d", TOKEN_NAME[token->type], token->line, token->column);
if (token->type != TOKEN_ERROR)
{
Log(LOG_INFO, "Token %s at line %d, column %d", TOKEN_NAME[token->type], token->line, token->column);
return;
}
Log(LOG_ERR, "ERROR(%d:%d) Invalid token", token->line, token->column);
}
void
@ -264,6 +327,7 @@ LexerNext(LexerState * state)
* There are no errors, since this is our "end" state */
return LexerReturnEOF(state);
}
LexerSaveCursor(state);
}
LexerUngetc(state, c);
@ -278,6 +342,7 @@ LexerNext(LexerState * state)
return LexerReturnSymbol(state, symbols[symbol].type);
}
}
/* We weren't able to find a proper symbol. Let's now find a keychar. */
c = LexerGetc(state);
if (c == EOF)
@ -286,15 +351,29 @@ LexerNext(LexerState * state)
* There are no errors, since this is our "end" state */
return LexerReturnEOF(state);
}
if (strchr(keychars, c))
for (symbol = 0; symbol < KEYCHAR_COUNT; symbol++)
{
if (c == keychars[symbol].c)
{
/* If our symbol matches, then we can plop in a token. */
return LexerReturnSymbol(state, keychars[symbol].type);
}
}
/* If the character is a comment, then skip everything until you meet a
* newline */
if (c == '#')
{
/* We found a keychar! TODO: Do something with it*/
return NULL;
while (LexerGetc(state) != '\n');
/* ... and recurse away. */
return LexerNext(state);
}
LexerUngetc(state, c);
break;
}
return NULL;
/* Emit an error.
* TODO: Make it more advanced */
LexerSaveCursor(state);
return LexerReturnSymbol(state, TOKEN_ERROR);
}
void

Loading…
Cancel
Save