pebblisp/src/tokens.c

113 lines
2.2 KiB
C
Raw Normal View History

2016-04-18 04:25:36 -04:00
#include "tokens.h"
#include <stdlib.h>
#ifdef STANDALONE
#include <stdio.h>
#else
2020-05-04 18:14:41 -04:00
#define printf(...) nf_tokenize(NULL)
2016-04-18 04:25:36 -04:00
#endif
/*
* Grammar:
* token
* expr
* (op expr expr)
* (list expr expr ... )
*/
// Is the char a standalone token?
2020-05-04 10:03:35 -04:00
static const char singleTokens[] = "()+-*/=";
2016-04-18 04:25:36 -04:00
int isSingle(const char c) {
int i = 0;
while(singleTokens[i] != '\0'){
if(singleTokens[i] == c)
return singleTokens[i];
i++;
}
return 0;
}
int isDigit(const char c) {
return c >= '0' && c <= '9';
}
2020-05-04 10:03:35 -04:00
int isWhitespace(const char c) {
return c == ' ' || c == '\t' || c == '\n';
}
int notWhitespace(const char c) {
return !isWhitespace(c);
}
2020-05-04 18:14:41 -04:00
// Return needs to be freed, if not null
struct Slice *nf_tokenize(const char *input)
2016-04-18 04:25:36 -04:00
{
if(!input)
return NULL;
struct Slice *slices = malloc(sizeof(struct Slice) * MAX_TOK_CNT);
int i = 0;
int slice = 0;
int parens = 0;
while(input[i] != '\0') {
2020-05-04 18:14:41 -04:00
//printf("input: '%c'\n", input[i]);
2020-05-04 10:03:35 -04:00
if(isWhitespace(input[i])) {
i++;
continue;
}
2016-04-18 04:25:36 -04:00
if(input[i] == '(') {
parens++;
} else if (input[i] == ')') {
parens--;
}
if(isSingle(input[i])) {
slices[slice].text = &input[i];
slices[slice].length = 1;
slice++;
i++;
2020-05-04 10:03:35 -04:00
} else {
slices[slice].text = &input[i];
//int (*check)(const char c) = isDigit(input[i])?
//&isDigit : &notWhitespace;
int l = 1;
while(!isWhitespace(input[++i]) && !isSingle(input[i])) {
l++;
2020-05-04 18:14:41 -04:00
//slices[slice].length = l;
//debugSlice(&slices[slice]);
2020-05-04 10:03:35 -04:00
}
slices[slice].length = l;
slice++;
}
/* } else if(isDigit(input[i])) {
2016-04-18 04:25:36 -04:00
slices[slice].text = &input[i];
int l = 1;
while(isDigit(input[++i]))
l++;
slices[slice].length = l;
slice++;
2020-05-04 10:03:35 -04:00
} else { // Other uncaught
2016-04-18 04:25:36 -04:00
i++;
}
2020-05-04 10:03:35 -04:00
*/
2016-04-18 04:25:36 -04:00
}
if(parens){
free(slices);
return NULL;
}
slices[slice].text = NULL;
slices[slice].length = 0;
return slices;
}