diff --git a/.ikc3_history b/.ikc3_history
index c479415..b1b03c4 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,4 +1,3 @@
-2
server = Socket.listen("192.168.2.50", "58000")
server_client = Socket.Buf.accept(server)
req = HTTP.Request.buf_parse(server_client.buf_rw.r)
@@ -97,3 +96,4 @@ File.ext("abc.def")
require HTTPd
HTTP.Event.version
HTTP.Event.version()
+%KC3.Operator{}
diff --git a/libkc3/buf.c b/libkc3/buf.c
index 7b41eca..27c4c6f 100644
--- a/libkc3/buf.c
+++ b/libkc3/buf.c
@@ -92,7 +92,7 @@ sw buf_ignore (s_buf *buf, uw size)
return r;
}
if (r > 0) {
- buf->column++;
+ buf->pretty.column++;
i += r;
continue;
}
@@ -659,11 +659,11 @@ sw buf_read_character_utf8 (s_buf *buf, character *p)
if (r > 0) {
if (buf->line >= 0) {
if (*p == '\n') {
- buf->column = 0;
+ buf->pretty.column = 0;
buf->line++;
}
else
- buf->column++;
+ buf->pretty.column++;
}
buf->rpos += r;
}
@@ -1130,9 +1130,23 @@ sw buf_vf (s_buf *buf, const char *fmt, va_list ap)
sw buf_write (s_buf *buf, const void *data, uw len)
{
- s_str str;
- str_init(&str, NULL, len, data);
- return buf_write_str_memcpy(buf, &str);
+ sw r;
+ assert(buf);
+ if (! len)
+ return 0;
+ if (buf->wpos > buf->size)
+ return -1;
+ if (buf->wpos + len > buf->size &&
+ (r = buf_flush(buf)) < (sw) len)
+ return -1;
+ if (buf->wpos + len > buf->size) {
+ assert(! "buffer overflow");
+ return -1;
+ }
+ memcpy(buf->ptr.ps8 + buf->wpos, data, len);
+ buf->wpos += len;
+ buf_flush(buf);
+ return len;
}
sw buf_write_1 (s_buf *buf, const char *p)
@@ -1151,9 +1165,15 @@ sw buf_write_1_size (s_pretty *pretty, const char *p)
sw buf_write_character_utf8 (s_buf *buf, character c)
{
- sw size = character_utf8_size(c);
- if (size <= 0)
- return size;
+ sw csize;
+ sw size;
+ csize = character_utf8_size(c);
+ if (csize <= 0)
+ return csize;
+ if (c == '\n')
+ size = csize + buf->pretty.base_column;
+ else
+ size = csize;
if (buf->wpos + size > buf->size &&
buf_flush(buf) < size) {
return -1;
@@ -1163,10 +1183,29 @@ sw buf_write_character_utf8 (s_buf *buf, character c)
return -1;
}
character_utf8(c, buf->ptr.pchar + buf->wpos);
+ if (c == '\n') {
+ memset(buf->ptr.pchar + buf->wpos + csize, ' ',
+ buf->pretty.base_column);
+ buf->pretty.column = buf->pretty.base_column;
+ }
+ else
+ buf->pretty.column++;
buf->wpos += size;
return size;
}
+sw buf_write_character_utf8_size (s_pretty *pretty, character c)
+{
+ sw size = character_utf8_size(c);
+ if (size <= 0)
+ return size;
+ if (c == '\n')
+ pretty->column = pretty->base_column;
+ else
+ pretty->column++;
+ return size;
+}
+
sw buf_write_f32 (s_buf *buf, f32 x)
{
const sw size = 4;
@@ -1257,7 +1296,6 @@ sw buf_write_s64 (s_buf *buf, s64 v)
sw buf_write_str (s_buf *buf, const s_str *src)
{
character c;
- uw i;
sw r;
sw result = 0;
s_str s;
@@ -1268,44 +1306,14 @@ sw buf_write_str (s_buf *buf, const s_str *src)
if ((r = buf_write_character_utf8(buf, c)) < 0)
return r;
result += r;
- if (c == '\n') {
- i = 0;
- while (i < buf->pretty.base_column) {
- if ((r = buf_write_u8(buf, ' ')) < 0)
- return r;
- result += r;
- i++;
- }
- }
}
buf_flush(buf);
return result;
}
-sw buf_write_str_memcpy (s_buf *buf, const s_str *src)
-{
- sw r;
- assert(buf);
- assert(src);
- if (buf->wpos > buf->size)
- return -1;
- if (buf->wpos + src->size > buf->size &&
- (r = buf_flush(buf)) < (sw) src->size)
- return -1;
- if (buf->wpos + src->size > buf->size) {
- assert(! "buffer overflow");
- return -1;
- }
- memcpy(buf->ptr.pu8 + buf->wpos, src->ptr.p, src->size);
- buf->wpos += src->size;
- buf_flush(buf);
- return src->size;
-}
-
sw buf_write_str_size (s_pretty *pretty, const s_str *src)
{
character c;
- uw i;
sw r;
sw result = 0;
s_str s;
@@ -1313,20 +1321,36 @@ sw buf_write_str_size (s_pretty *pretty, const s_str *src)
assert(src);
s = *src;
while ((r = str_read_character_utf8(&s, &c)) > 0) {
- if ((r = character_utf8_size(c)) < 0)
+ if ((r = buf_write_character_utf8_size(pretty, c)) < 0)
return r;
result += r;
- if (c == '\n') {
- i = 0;
- while (i < pretty->base_column) {
- result++;
- i++;
- }
- }
}
return result;
}
+sw buf_write_str_without_indent (s_buf *buf, const s_str *src)
+{
+ s_pretty_save pretty_save;
+ sw r;
+ pretty_save_init(&pretty_save, &buf->pretty);
+ pretty_indent_at_column(&buf->pretty, 0);
+ r = buf_write_str(buf, src);
+ pretty_save_clean(&pretty_save, &buf->pretty);
+ return r;
+}
+
+sw buf_write_str_without_indent_size (s_pretty *pretty,
+ const s_str *src)
+{
+ s_pretty_save pretty_save;
+ sw r;
+ pretty_save_init(&pretty_save, pretty);
+ pretty_indent_at_column(pretty, 0);
+ r = buf_write_str_size(pretty, src);
+ pretty_save_clean(&pretty_save, pretty);
+ return r;
+}
+
sw buf_write_u8 (s_buf *buf, u8 x)
{
const sw size = 1;
diff --git a/libkc3/buf.h b/libkc3/buf.h
index 4fe19f0..db96769 100644
--- a/libkc3/buf.h
+++ b/libkc3/buf.h
@@ -111,8 +111,10 @@ sw buf_write_s16 (s_buf *buf, s16 i);
sw buf_write_s32 (s_buf *buf, s32 i);
sw buf_write_s64 (s_buf *buf, s64 i);
sw buf_write_str (s_buf *buf, const s_str *src);
-sw buf_write_str_memcpy (s_buf *buf, const s_str *src);
sw buf_write_str_size (s_pretty *pretty, const s_str *src);
+sw buf_write_str_without_indent (s_buf *buf, const s_str *src);
+sw buf_write_str_without_indent_size (s_pretty *pretty,
+ const s_str *src);
sw buf_write_u8 (s_buf *buf, u8 i);
sw buf_write_u16 (s_buf *buf, u16 i);
sw buf_write_u32 (s_buf *buf, u32 i);
diff --git a/libkc3/buf_inspect.c b/libkc3/buf_inspect.c
index 961842a..21c87c4 100644
--- a/libkc3/buf_inspect.c
+++ b/libkc3/buf_inspect.c
@@ -252,7 +252,7 @@ sw buf_inspect_array_size (s_pretty *pretty, const s_array *array)
sw buf_inspect_block (s_buf *buf, const s_block *block)
{
- s_pretty pretty_save;
+ s_pretty_save pretty_save;
u64 i = 0;
sw r;
sw result = 0;
@@ -262,7 +262,7 @@ sw buf_inspect_block (s_buf *buf, const s_block *block)
else
return buf_write_1(buf, "do end");
}
- pretty_save = buf->pretty;
+ pretty_save_init(&pretty_save, &buf->pretty);
pretty_indent(&buf->pretty, PRETTY_INDENT);
if (block->short_form) {
if ((r = buf_write_1(buf, "{ ")) < 0)
@@ -291,7 +291,7 @@ sw buf_inspect_block (s_buf *buf, const s_block *block)
if ((r = buf_inspect_tag(buf, block->tag + i)) < 0)
return r;
result += r;
- buf->pretty = pretty_save;
+ pretty_save_clean(&pretty_save, &buf->pretty);
if (block->short_form) {
if ((r = buf_write_1(buf, " }")) < 0)
return r;
@@ -380,7 +380,7 @@ sw buf_inspect_block_inner_size (s_pretty *pretty, const s_block *block)
sw buf_inspect_block_size (s_pretty *pretty, const s_block *block)
{
- s_pretty pretty_save;
+ s_pretty_save pretty_save;
u64 i = 0;
sw r;
sw result = 0;
@@ -390,7 +390,7 @@ sw buf_inspect_block_size (s_pretty *pretty, const s_block *block)
else
return buf_write_1_size(pretty, "do end");
}
- pretty_save = *pretty;
+ pretty_save_init(&pretty_save, pretty);
pretty_indent(pretty, PRETTY_INDENT);
if (block->short_form) {
if ((r = buf_write_1_size(pretty, "{ ")) < 0)
@@ -419,7 +419,7 @@ sw buf_inspect_block_size (s_pretty *pretty, const s_block *block)
if ((r = buf_inspect_tag_size(pretty, block->tag + i)) < 0)
return r;
result += r;
- *pretty = pretty_save;
+ pretty_save_clean(&pretty_save, pretty);
if (block->short_form) {
if ((r = buf_write_1_size(pretty, " }")) < 0)
return r;
@@ -669,7 +669,7 @@ sw buf_inspect_call_if_then_else (s_buf *buf, const s_call *call)
s_tag *condition;
s_tag *else_;
uw i;
- s_pretty pretty_save;
+ s_pretty_save pretty_save;
sw r;
sw result = 0;
s_tag *then;
@@ -685,7 +685,7 @@ sw buf_inspect_call_if_then_else (s_buf *buf, const s_call *call)
return r;
result += r;
then = &list_next(call->arguments)->tag;
- pretty_save = buf->pretty;
+ pretty_save_init(&pretty_save, &buf->pretty);
if (then->type == TAG_BLOCK) {
if ((r = buf_write_1(buf, " do")) < 0)
return r;
@@ -705,13 +705,13 @@ sw buf_inspect_call_if_then_else (s_buf *buf, const s_call *call)
if ((r = buf_inspect_tag(buf, then)) < 0)
return r;
result += r;
- buf->pretty = pretty_save;
+ pretty_save_clean(&pretty_save, &buf->pretty);
else_ = &list_next(list_next(call->arguments))->tag;
if (else_->type != TAG_VOID) {
if ((r = buf_write_1(buf, "\nelse")) < 0)
return r;
result += r;
- pretty_save = buf->pretty;
+ pretty_save_init(&pretty_save, &buf->pretty);
pretty_indent(&buf->pretty, PRETTY_INDENT);
if (then->type == TAG_BLOCK) {
if ((r = buf_inspect_block_inner(buf, &else_->data.block)) < 0)
@@ -722,7 +722,7 @@ sw buf_inspect_call_if_then_else (s_buf *buf, const s_call *call)
return r;
result += r;
}
- buf->pretty = pretty_save;
+ pretty_save_clean(&pretty_save, &buf->pretty);
if ((r = buf_write_1(buf, "\nend")) < 0)
return r;
result += r;
@@ -734,7 +734,7 @@ sw buf_inspect_call_if_then_else_size (s_pretty *pretty, const s_call *call)
s_tag *condition;
s_tag *else_;
uw i;
- s_pretty pretty_save;
+ s_pretty_save pretty_save;
sw r;
sw result = 0;
s_tag *then;
@@ -750,7 +750,7 @@ sw buf_inspect_call_if_then_else_size (s_pretty *pretty, const s_call *call)
return r;
result += r;
then = &list_next(call->arguments)->tag;
- pretty_save = *pretty;
+ pretty_save_init(&pretty_save, pretty);
if (then->type == TAG_BLOCK) {
if ((r = buf_write_1_size(pretty, " do")) < 0)
return r;
@@ -772,12 +772,13 @@ sw buf_inspect_call_if_then_else_size (s_pretty *pretty, const s_call *call)
return r;
}
result += r;
- *pretty = pretty_save;
+ pretty_save_clean(&pretty_save, pretty);
else_ = &list_next(list_next(call->arguments))->tag;
if (else_->type != TAG_VOID) {
if ((r = buf_write_1_size(pretty, "\nelse")) < 0)
return r;
result += r;
+ pretty_save_init(&pretty_save, pretty);
if (then->type == TAG_BLOCK) {
if ((r = buf_inspect_block_inner_size(pretty,
&else_->data.block)) < 0)
@@ -788,6 +789,7 @@ sw buf_inspect_call_if_then_else_size (s_pretty *pretty, const s_call *call)
return r;
result += r;
}
+ pretty_save_clean(&pretty_save, pretty);
if ((r = buf_write_1_size(pretty, "\nend")) < 0)
return r;
result += r;
@@ -2703,7 +2705,7 @@ sw buf_inspect_str (s_buf *buf, const s_str *str)
if ((r = buf_write_u8(buf, '"')) <= 0)
goto clean;
result += r;
- if ((r = buf_write_str_memcpy(buf, str)) < 0)
+ if ((r = buf_write_str_without_indent(buf, str)) < 0)
goto restore;
result += r;
if ((r = buf_write_u8(buf, '"')) <= 0)
@@ -3018,6 +3020,7 @@ sw buf_inspect_struct (s_buf *buf, const s_struct *s)
{
uw i = 0;
s_tag *k;
+ s_pretty_save pretty_save;
sw r;
sw result = 0;
const s_sym *type;
@@ -3032,12 +3035,14 @@ sw buf_inspect_struct (s_buf *buf, const s_struct *s)
assert(! "buf_inspect_struct: sym_is_module(s->type->module)");
return -1;
}
- if ((r = buf_write_str_memcpy(buf, &s->type->module->str)) < 0)
+ if ((r = buf_write_str_without_indent(buf, &s->type->module->str)) < 0)
return r;
result += r;
if ((r = buf_write_1(buf, "{")) < 0)
return r;
result += r;
+ pretty_save_init(&pretty_save, &buf->pretty);
+ pretty_indent_from_column(&buf->pretty, 0);
if (s->data || s->tag) {
while (i < s->type->map.count) {
k = s->type->map.key + i;
@@ -3055,7 +3060,8 @@ sw buf_inspect_struct (s_buf *buf, const s_struct *s)
return r;
}
else
- if ((r = buf_write_str_memcpy(buf, &k->data.sym->str)) < 0)
+ if ((r = buf_write_str_without_indent(buf,
+ &k->data.sym->str)) < 0)
return r;
result += r;
if ((r = buf_write_1(buf, ": ")) < 0)
@@ -3077,7 +3083,7 @@ sw buf_inspect_struct (s_buf *buf, const s_struct *s)
}
i++;
if (i < s->type->map.count) {
- if ((r = buf_write_1(buf, ", ")) < 0)
+ if ((r = buf_write_1(buf, ",\n")) < 0)
return r;
result += r;
}
@@ -3086,6 +3092,7 @@ sw buf_inspect_struct (s_buf *buf, const s_struct *s)
if ((r = buf_write_1(buf, "}")) < 0)
return r;
result += r;
+ pretty_save_clean(&pretty_save, &buf->pretty);
return result;
}
@@ -3093,6 +3100,7 @@ sw buf_inspect_struct_size (s_pretty *pretty, const s_struct *s)
{
uw i = 0;
s_tag *k;
+ s_pretty_save pretty_save;
sw r;
sw result = 0;
const s_sym *type;
@@ -3103,10 +3111,15 @@ sw buf_inspect_struct_size (s_pretty *pretty, const s_struct *s)
result += r;
if (! sym_is_module(s->type->module))
return -1;
- result += s->type->module->str.size;
+ if ((r = buf_write_str_without_indent_size
+ (pretty, &s->type->module->str)) < 0)
+ return r;
+ result += r;
if ((r = buf_write_1_size(pretty, "{")) < 0)
return r;
result += r;
+ pretty_save_init(&pretty_save, pretty);
+ pretty_indent_from_column(pretty, 0);
if (s->data || s->tag) {
while (i < s->type->map.count) {
k = s->type->map.key + i;
@@ -3155,6 +3168,7 @@ sw buf_inspect_struct_size (s_pretty *pretty, const s_struct *s)
if ((r = buf_write_1_size(pretty, "}")) < 0)
return r;
result += r;
+ pretty_save_clean(&pretty_save, pretty);
return result;
}
diff --git a/libkc3/pretty.c b/libkc3/pretty.c
index 337130c..b916cff 100644
--- a/libkc3/pretty.c
+++ b/libkc3/pretty.c
@@ -10,9 +10,9 @@
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
+#include "io.h"
#include "pretty.h"
-/* Operators. */
s_pretty * pretty_indent (s_pretty *pretty, sw indent)
{
if ((sw) pretty->base_column + indent < 0)
@@ -20,3 +20,43 @@ s_pretty * pretty_indent (s_pretty *pretty, sw indent)
pretty->base_column += indent;
return pretty;
}
+
+s_pretty * pretty_indent_at_column (s_pretty *pretty, uw column)
+{
+ pretty->base_column = column;
+ return pretty;
+}
+
+s_pretty * pretty_indent_from_column (s_pretty *pretty, sw indent)
+{
+ if (false) {
+ err_write_1("pretty->column = ");
+ err_inspect_sw_decimal(&pretty->column);
+ err_write_1("\n");
+ }
+ if ((sw) pretty->column + indent < 0)
+ return NULL;
+ pretty->base_column = pretty->column + indent;
+ if (false) {
+ err_write_1("pretty->base_column = ");
+ err_inspect_uw_decimal(&pretty->base_column);
+ err_write_1("\n");
+ }
+ return pretty;
+}
+
+s_pretty * pretty_save_clean (const s_pretty_save *pretty_save,
+ s_pretty *pretty)
+{
+ pretty->base_column = pretty_save->base_column;
+ return pretty;
+}
+
+s_pretty_save * pretty_save_init (s_pretty_save *pretty_save,
+ const s_pretty *pretty)
+{
+ s_pretty_save tmp = {0};
+ tmp.base_column = pretty->base_column;
+ *pretty_save = tmp;
+ return pretty_save;
+}
diff --git a/libkc3/pretty.h b/libkc3/pretty.h
index 4a80faf..8224d38 100644
--- a/libkc3/pretty.h
+++ b/libkc3/pretty.h
@@ -23,7 +23,15 @@
#define PRETTY_INDENT 2
+/* Stack-allocation compatible functions, call *_clean after use. */
+s_pretty * pretty_save_clean (const s_pretty_save *pretty_save,
+ s_pretty *pretty);
+s_pretty_save * pretty_save_init (s_pretty_save *pretty_save,
+ const s_pretty *pretty);
+
/* Operators. */
s_pretty * pretty_indent (s_pretty *pretty, sw indent);
+s_pretty * pretty_indent_from_column (s_pretty *pretty, sw indent);
+s_pretty * pretty_indent_at_column (s_pretty *pretty, uw column);
#endif /* LIBKC3_LIST_H */
diff --git a/libkc3/types.h b/libkc3/types.h
index 63e1b28..5ce9c6a 100644
--- a/libkc3/types.h
+++ b/libkc3/types.h
@@ -173,6 +173,7 @@ typedef struct list s_list_map;
typedef struct log s_log;
typedef struct map s_map;
typedef struct pretty s_pretty;
+typedef struct pretty_save s_pretty_save;
typedef struct queue s_queue;
typedef struct quote s_quote;
typedef struct ratio s_ratio;
@@ -282,6 +283,11 @@ struct map {
struct pretty {
uw base_column;
+ sw column;
+};
+
+struct pretty_save {
+ uw base_column;
};
union ptr_ {
@@ -354,7 +360,6 @@ struct var {
/* 2 */
struct buf {
- sw column;
sw (*flush) (s_buf *buf);
bool free;
sw line;
diff --git a/test/ikc3/block.kc3 b/test/ikc3/block.kc3
index 8531e77..f0c90ce 100644
--- a/test/ikc3/block.kc3
+++ b/test/ikc3/block.kc3
@@ -53,3 +53,27 @@ do
def cast = cfn S32 "s32_init_cast" (Result, Sym, Tag)
end
+quote do
+ do
+ 1
+ end
+end
+do
+ do
+ 1
+ end
+end
+quote do
+ do
+ do
+ 1
+ end
+ end
+end
+do
+ do
+ do
+ 1
+ end
+ end
+end
diff --git a/test/ikc3/block.out.expected b/test/ikc3/block.out.expected
index 6e68758..7de59cd 100644
--- a/test/ikc3/block.out.expected
+++ b/test/ikc3/block.out.expected
@@ -48,6 +48,7 @@ do
1
end
end
+1
do
do
do
@@ -55,3 +56,4 @@ do
end
end
end
+1