mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 05:39:18 +02:00
Exception handling
This commit is contained in:
parent
bb1fdbb719
commit
0e01716827
1 changed files with 33 additions and 29 deletions
|
@ -11,7 +11,7 @@ static int digit_value (int c) {
|
||||||
|
|
||||||
sexp parse_json (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len);
|
sexp parse_json (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len);
|
||||||
|
|
||||||
sexp sexp_json_exception (sexp ctx, sexp self, const char* msg, sexp str, const int pos) {
|
sexp sexp_json_parse_exception (sexp ctx, sexp self, const char* msg, sexp str, const int pos) {
|
||||||
sexp_gc_var2(res, tmp);
|
sexp_gc_var2(res, tmp);
|
||||||
sexp_gc_preserve2(ctx, res, tmp);
|
sexp_gc_preserve2(ctx, res, tmp);
|
||||||
tmp = sexp_list2(ctx, str, sexp_make_fixnum(pos));
|
tmp = sexp_list2(ctx, str, sexp_make_fixnum(pos));
|
||||||
|
@ -20,6 +20,15 @@ sexp sexp_json_exception (sexp ctx, sexp self, const char* msg, sexp str, const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sexp sexp_json_unparse_exception (sexp ctx, sexp self, const char* msg, sexp obj) {
|
||||||
|
sexp_gc_var2(res, tmp);
|
||||||
|
sexp_gc_preserve2(ctx, res, tmp);
|
||||||
|
tmp = sexp_list1(ctx, obj);
|
||||||
|
res = sexp_user_exception(ctx, self, msg, tmp);
|
||||||
|
sexp_gc_release2(ctx);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
sexp parse_json_number (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len) {
|
sexp parse_json_number (sexp ctx, sexp self, sexp str, const char* s, int* i, const int len) {
|
||||||
double res = 0, scale = 1;
|
double res = 0, scale = 1;
|
||||||
int j = *i, sign = 1, inexactp = 0, scale_sign = 1;
|
int j = *i, sign = 1, inexactp = 0, scale_sign = 1;
|
||||||
|
@ -62,7 +71,7 @@ sexp parse_json_literal (sexp ctx, sexp self, sexp str, const char* s, int* i, c
|
||||||
res = value;
|
res = value;
|
||||||
*i += namelen;
|
*i += namelen;
|
||||||
} else {
|
} else {
|
||||||
res = sexp_json_exception(ctx, self, "unexpected character in json at", str, *i);
|
res = sexp_json_parse_exception(ctx, self, "unexpected character in json at", str, *i);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +96,7 @@ sexp parse_json_string (sexp ctx, sexp self, sexp str, const char* s, int* i, co
|
||||||
res = SEXP_NULL;
|
res = SEXP_NULL;
|
||||||
for ( ; s[to] != '"' && !sexp_exceptionp(res); ++to) {
|
for ( ; s[to] != '"' && !sexp_exceptionp(res); ++to) {
|
||||||
if (to+1 >= len) {
|
if (to+1 >= len) {
|
||||||
res = sexp_json_exception(ctx, self, "unterminated string in json started at", str, *i);
|
res = sexp_json_parse_exception(ctx, self, "unterminated string in json started at", str, *i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (s[to] == '\\') {
|
if (s[to] == '\\') {
|
||||||
|
@ -117,7 +126,7 @@ sexp parse_json_string (sexp ctx, sexp self, sexp str, const char* s, int* i, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (utfchar < 0) {
|
if (utfchar < 0) {
|
||||||
res = sexp_json_exception(ctx, self, "invalid \\u sequence at", str, to - USEQ_LEN);
|
res = sexp_json_parse_exception(ctx, self, "invalid \\u sequence at", str, to - USEQ_LEN);
|
||||||
} else {
|
} else {
|
||||||
tmp = sexp_make_string(ctx, sexp_make_fixnum(1), sexp_make_character(utfchar));
|
tmp = sexp_make_string(ctx, sexp_make_fixnum(1), sexp_make_character(utfchar));
|
||||||
res = sexp_cons(ctx, tmp, res);
|
res = sexp_cons(ctx, tmp, res);
|
||||||
|
@ -153,11 +162,11 @@ sexp parse_json_array (sexp ctx, sexp self, sexp str, const char* s, int* i, con
|
||||||
res = SEXP_NULL;
|
res = SEXP_NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (j >= len) {
|
if (j >= len) {
|
||||||
res = sexp_json_exception(ctx, self, "unterminated array in json started at", str, *i);
|
res = sexp_json_parse_exception(ctx, self, "unterminated array in json started at", str, *i);
|
||||||
break;
|
break;
|
||||||
} else if (s[j] == ']') {
|
} else if (s[j] == ']') {
|
||||||
if (comma && res != SEXP_NULL) {
|
if (comma && res != SEXP_NULL) {
|
||||||
res = sexp_json_exception(ctx, self, "missing value after comma in json array at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "missing value after comma in json array at", str, j);
|
||||||
} else {
|
} else {
|
||||||
res = sexp_nreverse(ctx, res);
|
res = sexp_nreverse(ctx, res);
|
||||||
res = sexp_list_to_vector(ctx, res);
|
res = sexp_list_to_vector(ctx, res);
|
||||||
|
@ -165,7 +174,7 @@ sexp parse_json_array (sexp ctx, sexp self, sexp str, const char* s, int* i, con
|
||||||
++j;
|
++j;
|
||||||
break;
|
break;
|
||||||
} else if (s[j] == ',' && comma) {
|
} else if (s[j] == ',' && comma) {
|
||||||
res = sexp_json_exception(ctx, self, "unexpected comma in json array at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "unexpected comma in json array at", str, j);
|
||||||
break;
|
break;
|
||||||
} else if (s[j] == ',') {
|
} else if (s[j] == ',') {
|
||||||
comma = 1;
|
comma = 1;
|
||||||
|
@ -182,7 +191,7 @@ sexp parse_json_array (sexp ctx, sexp self, sexp str, const char* s, int* i, con
|
||||||
res = sexp_cons(ctx, tmp, res);
|
res = sexp_cons(ctx, tmp, res);
|
||||||
comma = 0;
|
comma = 0;
|
||||||
} else {
|
} else {
|
||||||
res = sexp_json_exception(ctx, self, "unexpected value in json array at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "unexpected value in json array at", str, j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,18 +209,18 @@ sexp parse_json_object (sexp ctx, sexp self, sexp str, const char* s, int* i, co
|
||||||
res = SEXP_NULL;
|
res = SEXP_NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (j >= len) {
|
if (j >= len) {
|
||||||
res = sexp_json_exception(ctx, self, "unterminated object in json started at", str, *i);
|
res = sexp_json_parse_exception(ctx, self, "unterminated object in json started at", str, *i);
|
||||||
break;
|
break;
|
||||||
} else if (s[j] == '}') {
|
} else if (s[j] == '}') {
|
||||||
if (comma && res != SEXP_NULL) {
|
if (comma && res != SEXP_NULL) {
|
||||||
res = sexp_json_exception(ctx, self, "missing value after comma in json object at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "missing value after comma in json object at", str, j);
|
||||||
} else {
|
} else {
|
||||||
res = sexp_nreverse(ctx, res);
|
res = sexp_nreverse(ctx, res);
|
||||||
}
|
}
|
||||||
++j;
|
++j;
|
||||||
break;
|
break;
|
||||||
} else if (s[j] == ',' && comma) {
|
} else if (s[j] == ',' && comma) {
|
||||||
res = sexp_json_exception(ctx, self, "unexpected comma in json object at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "unexpected comma in json object at", str, j);
|
||||||
break;
|
break;
|
||||||
} else if (s[j] == ',') {
|
} else if (s[j] == ',') {
|
||||||
comma = 1;
|
comma = 1;
|
||||||
|
@ -231,7 +240,7 @@ sexp parse_json_object (sexp ctx, sexp self, sexp str, const char* s, int* i, co
|
||||||
while (j < len && isspace(s[j]))
|
while (j < len && isspace(s[j]))
|
||||||
++j;
|
++j;
|
||||||
if (s[j] != ':') {
|
if (s[j] != ':') {
|
||||||
res = sexp_json_exception(ctx, self, "missing colon in json object at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "missing colon in json object at", str, j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++j;
|
++j;
|
||||||
|
@ -243,7 +252,7 @@ sexp parse_json_object (sexp ctx, sexp self, sexp str, const char* s, int* i, co
|
||||||
res = sexp_cons(ctx, tmp, res);
|
res = sexp_cons(ctx, tmp, res);
|
||||||
comma = 0;
|
comma = 0;
|
||||||
} else {
|
} else {
|
||||||
res = sexp_json_exception(ctx, self, "unexpected value in json object at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "unexpected value in json object at", str, j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,13 +295,13 @@ sexp parse_json (sexp ctx, sexp self, sexp str, const char* s, int* i, const int
|
||||||
res = parse_json_literal(ctx, self, str, s, &j, len, "false", 5, SEXP_FALSE);
|
res = parse_json_literal(ctx, self, str, s, &j, len, "false", 5, SEXP_FALSE);
|
||||||
break;
|
break;
|
||||||
case '}':
|
case '}':
|
||||||
res = sexp_json_exception(ctx, self, "unexpected closing brace in json at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "unexpected closing brace in json at", str, j);
|
||||||
break;
|
break;
|
||||||
case ']':
|
case ']':
|
||||||
res = sexp_json_exception(ctx, self, "unexpected closing bracket in json at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "unexpected closing bracket in json at", str, j);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = sexp_json_exception(ctx, self, "unexpected character in json at", str, j);
|
res = sexp_json_parse_exception(ctx, self, "unexpected character in json at", str, j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*i = j;
|
*i = j;
|
||||||
|
@ -375,8 +384,8 @@ sexp unparse_json_string(sexp ctx, sexp self, const sexp obj){
|
||||||
chh = (0xD800 - (0x10000 >> 10) + ((ch) >> 10));
|
chh = (0xD800 - (0x10000 >> 10) + ((ch) >> 10));
|
||||||
chl = (0xDC00 + ((ch) & 0x3FF));
|
chl = (0xDC00 + ((ch) & 0x3FF));
|
||||||
if (chh > 0xFFFF || chl > 0xFFFF){
|
if (chh > 0xFFFF || chl > 0xFFFF){
|
||||||
// TODO: Create custom unparse exception
|
res = sexp_json_unparse_exception(ctx, self, "unable to encode string", obj);
|
||||||
res = sexp_json_exception(ctx, self, "unable to encode character at", obj, i);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
sprintf(cout, "\\u%04lX\\u%04lX", chh, chl);
|
sprintf(cout, "\\u%04lX\\u%04lX", chh, chl);
|
||||||
|
@ -407,7 +416,8 @@ sexp unparse_json_array(sexp ctx, sexp self, const sexp obj){
|
||||||
for (int i=0; i!=len; i++){
|
for (int i=0; i!=len; i++){
|
||||||
tmp = unparse_json(ctx, self, sexp_vector_ref(obj, sexp_make_fixnum(i)));
|
tmp = unparse_json(ctx, self, sexp_vector_ref(obj, sexp_make_fixnum(i)));
|
||||||
if (sexp_exceptionp(tmp)){
|
if (sexp_exceptionp(tmp)){
|
||||||
goto except;
|
sexp_gc_release2(ctx);
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
res = sexp_cons(ctx, tmp, res);
|
res = sexp_cons(ctx, tmp, res);
|
||||||
|
|
||||||
|
@ -423,7 +433,6 @@ sexp unparse_json_array(sexp ctx, sexp self, const sexp obj){
|
||||||
res = sexp_nreverse(ctx, res);
|
res = sexp_nreverse(ctx, res);
|
||||||
res = sexp_string_concatenate(ctx, res, SEXP_FALSE);
|
res = sexp_string_concatenate(ctx, res, SEXP_FALSE);
|
||||||
|
|
||||||
except:
|
|
||||||
sexp_gc_release2(ctx);
|
sexp_gc_release2(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -442,24 +451,19 @@ sexp unparse_json_object(sexp ctx, sexp self, const sexp obj){
|
||||||
for (int i=0; i!=len; i++){
|
for (int i=0; i!=len; i++){
|
||||||
cur = sexp_car(it);
|
cur = sexp_car(it);
|
||||||
if (!sexp_pairp(cur)){
|
if (!sexp_pairp(cur)){
|
||||||
/*
|
res = sexp_json_unparse_exception(ctx, self, "unable to encode key-value pair: not a pair", obj);
|
||||||
* TODO: Raise exception, must be a pair (key . val)
|
|
||||||
res = exception!
|
|
||||||
*/
|
|
||||||
goto except;
|
goto except;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key
|
// Key
|
||||||
key = sexp_car(cur);
|
key = sexp_car(cur);
|
||||||
if (!(sexp_symbolp(key) /*|| sexp_stringp(key)*/)){
|
if (!(sexp_symbolp(key) /*|| sexp_stringp(key)*/)){
|
||||||
/*
|
res = sexp_json_unparse_exception(ctx, self, "unable to encode key: not a symbol", key);
|
||||||
* TODO: Raise exception, key must be symbol (or string?)
|
|
||||||
res = exception!
|
|
||||||
*/
|
|
||||||
goto except;
|
goto except;
|
||||||
}
|
}
|
||||||
tmp = unparse_json(ctx, self, key);
|
tmp = unparse_json(ctx, self, key);
|
||||||
if (sexp_exceptionp(tmp)){
|
if (sexp_exceptionp(tmp)){
|
||||||
|
res = tmp;
|
||||||
goto except;
|
goto except;
|
||||||
}
|
}
|
||||||
res = sexp_cons(ctx, tmp, res);
|
res = sexp_cons(ctx, tmp, res);
|
||||||
|
@ -519,7 +523,7 @@ sexp unparse_json (sexp ctx, sexp self, sexp obj){
|
||||||
} else if (obj == SEXP_NULL){
|
} else if (obj == SEXP_NULL){
|
||||||
res = sexp_c_string(ctx, "null", -1);
|
res = sexp_c_string(ctx, "null", -1);
|
||||||
} else {
|
} else {
|
||||||
//res = sexp_json_exception(ctx, self, "unable to decode", obj, i);
|
res = sexp_json_unparse_exception(ctx, self, "unable to encode element", obj);
|
||||||
}
|
}
|
||||||
sexp_gc_release1(ctx);
|
sexp_gc_release1(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Add table
Reference in a new issue