added HCL_LOG_PREFER_JSON and implemented %J

This commit is contained in:
hyung-hwan 2018-03-02 07:44:13 +00:00
parent 450526215a
commit 60a32bf642
5 changed files with 107 additions and 54 deletions

26
README.md Normal file
View File

@ -0,0 +1,26 @@
# HCL - Hybrid Command Language
## Language Syntax
A HCL program is composed of 0 or more expressions.
## Special Form Expression
* break
* defun
* do
* elif
* else
* if
* lambda
* return
* set
* until
* while
## literals
* #nil
* #true
* #false

View File

@ -1011,7 +1011,6 @@ struct hcl_t
hcl_oop_t _else; /* symbol */
hcl_oop_t _if; /* symbol */
hcl_oop_t _lambda; /* symbol */
hcl_oop_t _quote; /* symbol */
hcl_oop_t _return; /* symbol */
hcl_oop_t _set; /* symbol */
hcl_oop_t _until; /* symbol */
@ -1176,8 +1175,9 @@ enum hcl_log_mask_t
HCL_LOG_STDOUT = (1 << 14), /* write log messages to stdout without timestamp. HCL_LOG_STDOUT wins over HCL_LOG_STDERR. */
HCL_LOG_STDERR = (1 << 15) /* write log messages to stderr without timestamp. */
HCL_LOG_STDERR = (1 << 15), /* write log messages to stderr without timestamp. */
HCL_LOG_PREFER_JSON = (1 << 30) /* write a object in the json format. don't set this explicitly. use %J instead */
};
typedef enum hcl_log_mask_t hcl_log_mask_t;

View File

@ -1002,6 +1002,11 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t
if (hcl_outfmtobj(hcl, data->mask, arg, outbfmt) <= -1) goto oops;
break;
case 'J':
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
if (hcl_outfmtobj(hcl, data->mask | HCL_LOG_PREFER_JSON, arg, outbfmt) <= -1) goto oops;
break;
number:
{
const hcl_ooch_t* nsptr;

View File

@ -588,6 +588,10 @@ static int logfmtv (hcl_t* hcl, const fmtchar_t* fmt, hcl_fmtout_t* data, va_lis
if (hcl_outfmtobj(hcl, data->mask, va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops;
break;
case 'J':
if (hcl_outfmtobj(hcl, data->mask | HCL_LOG_PREFER_JSON, va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops;
break;
#if 0
case 'e':
case 'E':

View File

@ -196,6 +196,34 @@ static HCL_INLINE int outfmt_obj (hcl_t* hcl, int mask, hcl_oop_t obj, hcl_outbf
print_stack_t ps;
int brand;
int word_index;
int word_offset;
int json;
static const hcl_bch_t *opening_parens[][2] =
{
{ "(", "(" }, /*HCL_CONCODE_XLIST */
{ "#(", "[" }, /*HCL_CONCODE_ARRAY */
{ "#[", "[" }, /*HCL_CONCODE_BYTEARRAY */
{ "#{", "{" }, /*HCL_CONCODE_DIC */
{ "[", "]" } /*HCL_CONCODE_QLIST */
};
static const hcl_bch_t *closing_parens[][2] =
{
{ ")", ")" }, /*HCL_CONCODE_XLIST */
{ ")", "]" }, /*HCL_CONCODE_ARRAY */
{ "]", "]" }, /*HCL_CONCODE_BYTEARRAY */
{ "}", "}" }, /*HCL_CONCODE_DIC */
{ "]", "]" } /*HCL_CONCODE_QLIST */
};
static const hcl_bch_t* breakers[][2] =
{
{ " ", "," }, /* item breaker */
{ " ", ":" } /* key value breaker */
};
json = !!(mask & HCL_LOG_PREFER_JSON);
next:
switch ((brand = HCL_BRANDOF(hcl, obj)))
@ -223,14 +251,17 @@ next:
case HCL_BRAND_NIL:
word_index = WORD_NIL;
word_offset = json;
goto print_word;
case HCL_BRAND_TRUE:
word_index = WORD_TRUE;
word_offset = json;
goto print_word;
case HCL_BRAND_FALSE:
word_index = WORD_FALSE;
word_offset = json;
goto print_word;
case HCL_BRAND_PBIGINT:
@ -311,28 +342,13 @@ next:
case HCL_BRAND_CONS:
{
static hcl_bch_t *opening_paren[] =
{
"(", /*HCL_CONCODE_XLIST */
"#(", /*HCL_CONCODE_ARRAY */
"#[", /*HCL_CONCODE_BYTEARRAY */
"#{", /*HCL_CONCODE_DIC */
"[" /*HCL_CONCODE_QLIST */
};
static hcl_bch_t *closing_paren[] =
{
")", /*HCL_CONCODE_XLIST */
")", /*HCL_CONCODE_ARRAY */
"]", /*HCL_CONCODE_BYTEARRAY */
"}", /*HCL_CONCODE_DIC */
"]" /*HCL_CONCODE_QLIST */
};
int concode;
/* this part is to print a linked list of cells. ignore the
* request to output in the json format */
concode = HCL_OBJ_GET_FLAGS_SYNCODE(obj);
if (outbfmt(hcl, mask, opening_paren[concode]) <= -1) return -1;
if (outbfmt(hcl, mask, opening_parens[concode][0]) <= -1) return -1;
cur = obj;
do
@ -384,11 +400,11 @@ next:
}
/* The CDR part points to a pair. proceed to it */
if (outbfmt(hcl, mask, " ") <= -1) return -1;
if (outbfmt(hcl, mask, breakers[0][0]) <= -1) return -1;
}
while (1);
if (outbfmt(hcl, mask, closing_paren[concode]) <= -1) return -1;
if (outbfmt(hcl, mask, closing_parens[concode][0]) <= -1) return -1;
break;
}
@ -396,11 +412,11 @@ next:
{
hcl_oow_t arridx;
if (outbfmt(hcl, mask, "#(") <= -1) return -1;
if (outbfmt(hcl, mask, opening_parens[HCL_CONCODE_ARRAY][json]) <= -1) return -1;
if (HCL_OBJ_GET_SIZE(obj) <= 0)
{
if (outbfmt(hcl, mask, ")") <= -1) return -1;
if (outbfmt(hcl, mask, closing_parens[HCL_CONCODE_ARRAY][json]) <= -1) return -1;
break;
}
arridx = 0;
@ -428,7 +444,7 @@ next:
obj = ((hcl_oop_oop_t)obj)->slot[arridx];
if (arridx > 0)
{
if (outbfmt(hcl, mask, " ") <= -1) return -1;
if (outbfmt(hcl, mask, breakers[0][json]) <= -1) return -1;
}
/* Jump to the 'next' label so that the object
* pointed to by 'obj' is printed. Once it
@ -448,14 +464,16 @@ next:
case HCL_BRAND_BYTE_ARRAY:
{
hcl_oow_t i;
if (outbfmt(hcl, mask, "#[") <= -1) return -1;
for (i = 0; i < HCL_OBJ_GET_SIZE(obj); i++)
if (outbfmt(hcl, mask, opening_parens[HCL_CONCODE_BYTEARRAY][json]) <= -1) return -1;
if (HCL_OBJ_GET_SIZE(obj) > 0)
{
if (outbfmt(hcl, mask, "%hs%d", ((i > 0)? " ": ""), ((hcl_oop_byte_t)obj)->slot[i]) <= -1) return -1;
if (outbfmt(hcl, mask, "%d", ((hcl_oop_byte_t)obj)->slot[0]) <= -1) return -1;
for (i = 1; i < HCL_OBJ_GET_SIZE(obj); i++)
{
if (outbfmt(hcl, mask, "%hs%d", breakers[0][json], ((hcl_oop_byte_t)obj)->slot[i]) <= -1) return -1;
}
if (outbfmt(hcl, mask, "]") <= -1) return -1;
}
if (outbfmt(hcl, mask, closing_parens[HCL_CONCODE_BYTEARRAY][json]) <= -1) return -1;
break;
}
@ -464,13 +482,13 @@ next:
hcl_oow_t bucidx, bucsize, buctally;
hcl_oop_dic_t dic;
if (outbfmt(hcl, mask, "#{") <= -1) return -1;
if (outbfmt(hcl, mask, opening_parens[HCL_CONCODE_DIC][json]) <= -1) return -1;
dic = (hcl_oop_dic_t)obj;
HCL_ASSERT (hcl, HCL_OOP_IS_SMOOI(dic->tally));
if (HCL_OOP_TO_SMOOI(dic->tally) <= 0)
{
if (outbfmt(hcl, mask, "}") <= -1) return -1;
if (outbfmt(hcl, mask, closing_parens[HCL_CONCODE_DIC][json]) <= -1) return -1;
break;
}
bucidx = 0;
@ -496,7 +514,7 @@ next:
if (bucidx >= bucsize)
{
/* done. scanned the entire bucket */
if (outbfmt(hcl, mask, "}") <= -1) return -1;
if (outbfmt(hcl, mask, closing_parens[HCL_CONCODE_DIC][json]) <= -1) return -1;
break;
}
@ -537,7 +555,7 @@ next:
if (buctally > 0)
{
if (outbfmt(hcl, mask, " ") <= -1) return -1;
if (outbfmt(hcl, mask, breakers[buctally & 1][json]) <= -1) return -1;
}
/* Jump to the 'next' label so that the object
@ -606,7 +624,7 @@ next:
return -1;
print_word:
if (outbfmt(hcl, mask, "%.*js", word[word_index].len, word[word_index].ptr) <= -1) return -1;
if (outbfmt(hcl, mask, "%.*js", word[word_index].len - word_offset, word[word_index].ptr + word_offset) <= -1) return -1;
break;
}