1
0
mirror of https://github.com/janet-lang/janet synced 2025-05-08 18:34:14 +00:00

Add callgrind task to Makefile.

Unify some parser states.
This commit is contained in:
Calvin Rose 2019-01-06 21:49:24 -05:00
parent eae4e0dede
commit be85196de8
3 changed files with 65 additions and 74 deletions

1
.gitignore vendored
View File

@ -39,6 +39,7 @@ tags
# Valgrind files # Valgrind files
vgcore.* vgcore.*
*.out.*
# Created by https://www.gitignore.io/api/c # Created by https://www.gitignore.io/api/c

View File

@ -149,6 +149,9 @@ valtest: $(JANET_TARGET) $(TEST_PROGRAMS)
for f in build/*.out; do $(VALGRIND_COMMAND) "$$f" || exit; done for f in build/*.out; do $(VALGRIND_COMMAND) "$$f" || exit; done
for f in test/*.janet; do $(VALGRIND_COMMAND) ./$(JANET_TARGET) "$$f" || exit; done for f in test/*.janet; do $(VALGRIND_COMMAND) ./$(JANET_TARGET) "$$f" || exit; done
callgrind: $(JANET_TARGET)
for f in test/*.janet; do valgrind --tool=callgrind ./$(JANET_TARGET) "$$f" || exit; done
######################## ########################
##### Distribution ##### ##### Distribution #####
######################## ########################
@ -174,7 +177,7 @@ build/doc.html: $(JANET_TARGET) tools/gendoc.janet
################# #################
clean: clean:
-rm -rf build -rm -rf build vgcore.* callgrind.*
install: $(JANET_TARGET) install: $(JANET_TARGET)
mkdir -p $(BINDIR) mkdir -p $(BINDIR)

View File

@ -140,7 +140,7 @@ DEF_PARSER_STACK(_pushstate, JanetParseState, states, statecount, statecap)
#define PFLAG_STRING 0x2000 #define PFLAG_STRING 0x2000
#define PFLAG_LONGSTRING 0x4000 #define PFLAG_LONGSTRING 0x4000
#define PFLAG_READERMAC 0x8000 #define PFLAG_READERMAC 0x8000
#define PFLAG_PAIR 0x10000 #define PFLAG_ATSYM 0x10000
static void pushstate(JanetParser *p, Consumer consumer, int flags) { static void pushstate(JanetParser *p, Consumer consumer, int flags) {
JanetParseState s; JanetParseState s;
@ -331,78 +331,39 @@ static int comment(JanetParser *p, JanetParseState *state, uint8_t c) {
return 1; return 1;
} }
/* Forward declaration */ static Janet close_tuple(JanetParser *p, JanetParseState *state) {
static int root(JanetParser *p, JanetParseState *state, uint8_t c); Janet *ret = janet_tuple_begin(state->argn);
for (int32_t i = state->argn - 1; i >= 0; i--)
static int dotuple(JanetParser *p, JanetParseState *state, uint8_t c) { ret[i] = p->args[--p->argcount];
if (state->flags & PFLAG_SQRBRACKETS return janet_wrap_tuple(janet_tuple_end(ret));
? c == ']'
: c == ')') {
int32_t i;
Janet *ret = janet_tuple_begin(state->argn);
for (i = state->argn - 1; i >= 0; i--) {
ret[i] = p->args[--p->argcount];
}
popstate(p, janet_wrap_tuple(janet_tuple_end(ret)));
return 1;
}
return root(p, state, c);
} }
static int doarray(JanetParser *p, JanetParseState *state, uint8_t c) { static Janet close_array(JanetParser *p, JanetParseState *state) {
if (state->flags & PFLAG_SQRBRACKETS JanetArray *array = janet_array(state->argn);
? c == ']' for (int32_t i = state->argn - 1; i >= 0; i--)
: c == ')') { array->data[i] = p->args[--p->argcount];
int32_t i; array->count = state->argn;
JanetArray *array = janet_array(state->argn); return janet_wrap_array(array);
for (i = state->argn - 1; i >= 0; i--) {
array->data[i] = p->args[--p->argcount];
}
array->count = state->argn;
popstate(p, janet_wrap_array(array));
return 1;
}
return root(p, state, c);
} }
static int dostruct(JanetParser *p, JanetParseState *state, uint8_t c) { static Janet close_struct(JanetParser *p, JanetParseState *state) {
if (c == '}') { JanetKV *st = janet_struct_begin(state->argn >> 1);
int32_t i; for (int32_t i = state->argn; i > 0; i -= 2) {
JanetKV *st; Janet value = p->args[--p->argcount];
if (state->argn & 1) { Janet key = p->args[--p->argcount];
p->error = "struct literal expects even number of arguments"; janet_struct_put(st, key, value);
return 1;
}
st = janet_struct_begin(state->argn >> 1);
for (i = state->argn; i > 0; i -= 2) {
Janet value = p->args[--p->argcount];
Janet key = p->args[--p->argcount];
janet_struct_put(st, key, value);
}
popstate(p, janet_wrap_struct(janet_struct_end(st)));
return 1;
} }
return root(p, state, c); return janet_wrap_struct(janet_struct_end(st));
} }
static int dotable(JanetParser *p, JanetParseState *state, uint8_t c) { static Janet close_table(JanetParser *p, JanetParseState *state) {
if (c == '}') { JanetTable *table = janet_table(state->argn >> 1);
int32_t i; for (int32_t i = state->argn; i > 0; i -= 2) {
JanetTable *table; Janet value = p->args[--p->argcount];
if (state->argn & 1) { Janet key = p->args[--p->argcount];
p->error = "table literal expects even number of arguments"; janet_table_put(table, key, value);
return 1;
}
table = janet_table(state->argn >> 1);
for (i = state->argn; i > 0; i -= 2) {
Janet value = p->args[--p->argcount];
Janet key = p->args[--p->argcount];
janet_table_put(table, key, value);
}
popstate(p, janet_wrap_table(table));
return 1;
} }
return root(p, state, c); return janet_wrap_table(table);
} }
#define PFLAG_INSTRING 0x100000 #define PFLAG_INSTRING 0x100000
@ -449,12 +410,14 @@ static int longstring(JanetParser *p, JanetParseState *state, uint8_t c) {
} }
} }
static int root(JanetParser *p, JanetParseState *state, uint8_t c);
static int ampersand(JanetParser *p, JanetParseState *state, uint8_t c) { static int ampersand(JanetParser *p, JanetParseState *state, uint8_t c) {
(void) state; (void) state;
p->statecount--; p->statecount--;
switch (c) { switch (c) {
case '{': case '{':
pushstate(p, dotable, PFLAG_CONTAINER | PFLAG_CURLYBRACKETS); pushstate(p, root, PFLAG_CONTAINER | PFLAG_CURLYBRACKETS | PFLAG_ATSYM);
return 1; return 1;
case '"': case '"':
pushstate(p, stringchar, PFLAG_BUFFER | PFLAG_STRING); pushstate(p, stringchar, PFLAG_BUFFER | PFLAG_STRING);
@ -463,10 +426,10 @@ static int ampersand(JanetParser *p, JanetParseState *state, uint8_t c) {
pushstate(p, longstring, PFLAG_BUFFER | PFLAG_LONGSTRING); pushstate(p, longstring, PFLAG_BUFFER | PFLAG_LONGSTRING);
return 1; return 1;
case '[': case '[':
pushstate(p, doarray, PFLAG_CONTAINER | PFLAG_SQRBRACKETS); pushstate(p, root, PFLAG_CONTAINER | PFLAG_SQRBRACKETS | PFLAG_ATSYM);
return 1; return 1;
case '(': case '(':
pushstate(p, doarray, PFLAG_CONTAINER | PFLAG_PARENS); pushstate(p, root, PFLAG_CONTAINER | PFLAG_PARENS | PFLAG_ATSYM);
return 1; return 1;
default: default:
break; break;
@ -478,7 +441,6 @@ static int ampersand(JanetParser *p, JanetParseState *state, uint8_t c) {
/* The root state of the parser */ /* The root state of the parser */
static int root(JanetParser *p, JanetParseState *state, uint8_t c) { static int root(JanetParser *p, JanetParseState *state, uint8_t c) {
(void) state;
switch (c) { switch (c) {
default: default:
if (is_whitespace(c)) return 1; if (is_whitespace(c)) return 1;
@ -509,16 +471,41 @@ static int root(JanetParser *p, JanetParseState *state, uint8_t c) {
case ')': case ')':
case ']': case ']':
case '}': case '}':
p->error = "mismatched delimiter"; {
Janet ds;
if (p->statecount == 1) {
p->error = "mismatched delimiter";
return 1;
}
if ((c == ')' && (state->flags & PFLAG_PARENS)) ||
(c == ']' && (state->flags & PFLAG_SQRBRACKETS))) {
if (state->flags & PFLAG_ATSYM) {
ds = close_array(p, state);
} else {
ds = close_tuple(p, state);
}
} else if (c == '}' && (state->flags & PFLAG_CURLYBRACKETS)) {
if (state->argn & 1) {
p->error = "struct and table literals expect even number of arguments";
return 1;
}
if (state->flags & PFLAG_ATSYM) {
ds = close_table(p, state);
} else {
ds = close_struct(p, state);
}
}
popstate(p, ds);
}
return 1; return 1;
case '(': case '(':
pushstate(p, dotuple, PFLAG_CONTAINER | PFLAG_PARENS); pushstate(p, root, PFLAG_CONTAINER | PFLAG_PARENS);
return 1; return 1;
case '[': case '[':
pushstate(p, dotuple, PFLAG_CONTAINER | PFLAG_SQRBRACKETS); pushstate(p, root, PFLAG_CONTAINER | PFLAG_SQRBRACKETS);
return 1; return 1;
case '{': case '{':
pushstate(p, dostruct, PFLAG_CONTAINER | PFLAG_CURLYBRACKETS); pushstate(p, root, PFLAG_CONTAINER | PFLAG_CURLYBRACKETS);
return 1; return 1;
} }
} }