Files
BrainFuck/bf.c
2024-09-12 16:40:39 +02:00

140 lines
3.5 KiB
C

/*
* Created by Lionel Sambuc on 03.dec.2009.
* Copyright 2009-2010. All rights reserved.
*
*/
/**************************************************************************
* Brainfuck lexer *
**************************************************************************/
#include <string.h>
#include "interpreter.h"
#include "tokenizer.h"
#include "bf.h"
static char bf[NB_KWS];
/**************************************************************************
* PRIVATE INTERFACE *
**************************************************************************/
/**
* Brainfuck separator detector.
* Simply check whether the given character is one of the 8 reserved
* characters, if not it is a separator.
*/
static int brainfuck_is_separator(char c)
{
return !(c == '<' || c == '>' ||
c == '+' || c == '-' ||
c == '.' || c == ',' ||
c == '[' || c == ']');
}
/**
* Read a token from the program stream, in the given direction.
* Parameters :
* * direction positive : go from the left to the right
* negative : go from the right to the left
* zero : invalid direction.
* * program the program from which to read a token
* * token_start the actual position within the program
* * length the length of the program
*/
static int read_token(int direction, char const *program, int *token_start, size_t length)
{
char token;
size_t token_length;
/* Check that we have a sane direction. */
if(direction == 0)
return UKW;
/* Read the next token. */
if(direction > 0)
{
/* Try to find the next token. */
if(!tk_next_token(program, token_start, &token_length))
return EOT; /* It was not found. */
/* Save the token to be analyzed. */
token = *(program + *token_start);
/* Update the pointer to be __after__ the token we are analyzing.
* A simple increment does the job as we have only one character tokens.
*/
(*token_start)++;
}
/* Read the previous token. */
if(direction < 0)
{
/* Update the pointer to be __on the last character__ of the token we
* are analyzing. A simple decrement does the job as we have only one
* character tokens.
*/
(*token_start)--;
/* Try to find the previous token. */
if(!tk_previous_token(program, token_start, &token_length))
return SOT;/* It was not found. */
/* Save the token to be analyzed. */
token = *(program + *token_start);
}
/* Match the token characters to a known token value. */
if(bf[MVL] == token)
return MVL;
if(bf[MVR] == token)
return MVR;
if(bf[INC] == token)
return INC;
if(bf[DEC] == token)
return DEC;
if(bf[PUT] == token)
return PUT;
if(bf[GET] == token)
return GET;
if(bf[JZF] == token)
return JZF;
if(bf[JNB] == token)
return JNB;
return UKW;
}
/**************************************************************************
* PUBLIC INTERFACE *
**************************************************************************/
void brainfuck_lexer_init()
{
bf[MVR] = '>';
bf[MVL] = '<';
bf[INC] = '+';
bf[DEC] = '-';
bf[PUT] = '.';
bf[GET] = ',';
bf[JZF] = '[';
bf[JNB] = ']';
tk_is_separator = brainfuck_is_separator;
}
int brainfuck_read_next_token(char const *program, int *token_start, size_t length)
{
return read_token(+1, program, token_start, length);
}
int brainfuck_read_previous_token(char const *program, int *token_start, size_t length)
{
return read_token(-1, program, token_start, length);
}