summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2010-02-10 00:35:23 +0100
committerJohannes Weiner <hannes@cmpxchg.org>2010-02-10 00:35:23 +0100
commit016a2b6a4f98b1b641a3acc73fc418f5b68089c3 (patch)
tree6030b0961c036a5905c133f5f9a1e3d8c7ba5e7c
parent05d116ae81e6f33f61567411ccecb54e8807b166 (diff)
compile: sheep_parser_error()
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
-rw-r--r--include/sheep/compile.h2
-rw-r--r--sheep/compile.c52
-rw-r--r--sheep/core.c12
3 files changed, 29 insertions, 37 deletions
diff --git a/include/sheep/compile.h b/include/sheep/compile.h
index 61a97b5..003eaf4 100644
--- a/include/sheep/compile.h
+++ b/include/sheep/compile.h
@@ -46,7 +46,7 @@ struct sheep_context {
* @sheep: object to compile
*/
-void sheep_compiler_error(struct sheep_compile *, sheep_t, const char *, ...);
+void sheep_parser_error(struct sheep_compile *, sheep_t, const char *, ...);
static inline int sheep_compile_object(struct sheep_compile *compile,
struct sheep_function *function,
diff --git a/sheep/compile.c b/sheep/compile.c
index 87fb489..fbbf680 100644
--- a/sheep/compile.c
+++ b/sheep/compile.c
@@ -52,28 +52,32 @@ sheep_t __sheep_compile(struct sheep_vm *vm, struct sheep_module *module,
return sheep_make_object(vm, &sheep_function_type, function);
}
-void sheep_compiler_error(struct sheep_compile *compile, sheep_t sheep,
+void sheep_parser_error(struct sheep_compile *compile, sheep_t culprit,
const char *fmt, ...)
{
struct sheep_expr *expr = compile->expr;
- unsigned long offset;
+ unsigned long position;
+ const char *repr;
va_list ap;
if (sheep_type(expr->object) == &sheep_list_type) {
- struct sheep_list *form;
+ struct sheep_list *list = sheep_list(expr->object);
- form = sheep_list(expr->object);
- offset = 1; /* list itself is at 0 */
- sheep_list_search(form, sheep, &offset);
+ position = 1; /* list itself is at 0 */
+ sheep_list_search(list, culprit, &position);
} else
- offset = 0;
+ position = 0;
fprintf(stderr, "%s:%lu: ", expr->filename,
- (unsigned long)expr->lines.items[offset]);
+ (unsigned long)expr->lines.items[position]);
+
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
- fprintf(stderr, "\n");
+
+ repr = sheep_repr(culprit);
+ fprintf(stderr, " `%s'\n", repr);
+ sheep_free(repr);
}
int sheep_compile_constant(struct sheep_compile *compile,
@@ -168,7 +172,7 @@ static int compile_simple_name(struct sheep_compile *compile,
switch (lookup_env(compile, context, name, &dist, &slot)) {
case ENV_NONE:
- sheep_compiler_error(compile, sheep, "unbound name: %s", name);
+ sheep_parser_error(compile, sheep, "unbound name");
return -1;
case ENV_LOCAL:
if (set)
@@ -188,8 +192,8 @@ static int compile_simple_name(struct sheep_compile *compile,
break;
case ENV_BUILTIN:
if (set) {
- sheep_compiler_error(compile, sheep,
- "read-only bound name: %s", name);
+ sheep_parser_error(compile, sheep,
+ "can not change read-only binding to");
return -1;
}
sheep_emit(&function->code, SHEEP_GLOBAL, slot);
@@ -207,7 +211,6 @@ static int compile_name(struct sheep_compile *compile,
struct sheep_name *name;
unsigned int i = 0;
void *entry;
- char *tmp;
name = sheep_name(sheep);
if (name->nr_parts == 1)
@@ -236,9 +239,7 @@ static int compile_name(struct sheep_compile *compile,
sheep_emit(&function->code, SHEEP_GLOBAL, (unsigned long)entry);
return 0;
err:
- tmp = sheep_repr(sheep);
- sheep_compiler_error(compile, sheep, "unbound name: %s", tmp);
- sheep_free(tmp);
+ sheep_parser_error(compile, sheep, "unbound");
return -1;
}
@@ -410,26 +411,17 @@ static int parse(struct sheep_compile *compile, struct sheep_list *form,
{
unsigned int ret;
sheep_t mismatch;
- const char *name;
ret = __parse(child, items, &mismatch, ap);
if (ret == PARSE_OK)
return 0;
- name = sheep_repr(form->head);
- if (ret == PARSE_MISMATCH) {
- const char *culprit;
-
- culprit = sheep_repr(mismatch);
- sheep_compiler_error(compile, mismatch,
- "%s: parser error near `%s'",
- name, culprit);
- sheep_free(culprit);
- } else
- sheep_compiler_error(compile, child->head,
- "%s: too %s arguments", name,
+ if (ret == PARSE_MISMATCH)
+ sheep_parser_error(compile, mismatch, "parser error at");
+ else
+ sheep_parser_error(compile, form->head, "too %s arguments to",
ret == PARSE_TOO_MANY ? "many" : "few");
- sheep_free(name);
+
return -1;
}
diff --git a/sheep/core.c b/sheep/core.c
index 217057e..13dbd2d 100644
--- a/sheep/core.c
+++ b/sheep/core.c
@@ -206,21 +206,22 @@ static int compile_function(struct sheep_compile *compile,
childfun = sheep_data(sheep);
while (parms->head) {
+ struct sheep_list *rest;
unsigned int slot;
const char *parm;
- if (__sheep_parse(compile, args, parms, "sr", &parm, &parms))
+ if (__sheep_parse(compile, args, parms, "sr", &parm, &rest))
goto out;
slot = sheep_function_local(childfun);
if (sheep_map_set(&env, parm, (void *)(unsigned long)slot)) {
- sheep_compiler_error(compile, parms->head,
- "function: duplicate parameter `%s'",
- parm);
+ sheep_parser_error(compile, parms->head,
+ "duplicate function parameter");
goto out;
}
childfun->nr_parms++;
+ parms = rest;
}
cslot = sheep_vm_constant(compile->vm, sheep);
@@ -401,8 +402,7 @@ static int compile_load(struct sheep_compile *compile,
sheep_t mod;
if (context->parent) {
- sheep_compiler_error(compile, args->head,
- "load: not on toplevel");
+ sheep_parser_error(compile, args->head, "non-toplevel");
return -1;
}