pebblisp/src/tokens.c

107 lines
2.0 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>
#undef printd
#define printd(...) fprintf(stderr, __VA_ARGS__)
2016-04-18 04:25:36 -04:00
#else
#include <pebble.h>
#undef printd
#define printd(...) printf(__VA_ARGS__)
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') {
int l = 1;
// printd("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--;
2020-05-08 02:29:06 -04:00
if(parens < 0) {
free(slices);
return NULL;
}
2016-04-18 04:25:36 -04:00
}
slices[slice].text = &input[i];
2016-04-18 04:25:36 -04:00
if(isSingle(input[i])) {
i++;
} else if(input[i] == '"') {
while(input[++i] != '"') {
l++;
}
i++;
2020-05-04 10:03:35 -04:00
} else {
while(!isWhitespace(input[++i]) && !isSingle(input[i])) {
l++;
}
}
slices[slice].length = l;
slice++;
2016-04-18 04:25:36 -04:00
}
if(parens){
free(slices);
return NULL;
}
slices[slice].text = NULL;
slices[slice].length = 0;
return slices;
}